From 07ecc0ffd69515cade1c74e26c6587b8e97cd6fc Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Mon, 17 Feb 2025 11:03:36 -0800 Subject: [PATCH] Send the "encryption_passphrase" option to Borg via an anonymous pipe. --- NEWS | 2 + borgmatic/actions/check.py | 2 +- borgmatic/borg/borg.py | 2 +- borgmatic/borg/break_lock.py | 2 +- borgmatic/borg/change_passphrase.py | 2 +- borgmatic/borg/check.py | 2 +- borgmatic/borg/compact.py | 2 +- borgmatic/borg/create.py | 8 +- borgmatic/borg/delete.py | 2 +- borgmatic/borg/environment.py | 43 ++++-- borgmatic/borg/export_key.py | 2 +- borgmatic/borg/export_tar.py | 2 +- borgmatic/borg/extract.py | 8 +- borgmatic/borg/info.py | 4 +- borgmatic/borg/list.py | 6 +- borgmatic/borg/mount.py | 4 +- borgmatic/borg/passcommand.py | 16 +- borgmatic/borg/prune.py | 2 +- borgmatic/borg/repo_create.py | 2 +- borgmatic/borg/repo_delete.py | 2 +- borgmatic/borg/repo_info.py | 4 +- borgmatic/borg/repo_list.py | 6 +- borgmatic/borg/transfer.py | 2 +- borgmatic/borg/version.py | 2 +- borgmatic/execute.py | 74 ++++----- borgmatic/hooks/command.py | 14 +- borgmatic/hooks/data_source/mariadb.py | 39 ++--- borgmatic/hooks/data_source/mysql.py | 39 ++--- borgmatic/hooks/data_source/postgresql.py | 46 +++--- tests/unit/borg/test_borg.py | 30 ++-- tests/unit/borg/test_break_lock.py | 2 +- tests/unit/borg/test_change_passphrase.py | 2 +- tests/unit/borg/test_check.py | 14 +- tests/unit/borg/test_compact.py | 2 +- tests/unit/borg/test_create.py | 38 ++--- tests/unit/borg/test_delete.py | 6 +- tests/unit/borg/test_environment.py | 64 +++++--- tests/unit/borg/test_export_key.py | 2 +- tests/unit/borg/test_export_tar.py | 2 +- tests/unit/borg/test_extract.py | 8 +- tests/unit/borg/test_info.py | 4 +- tests/unit/borg/test_list.py | 24 +-- tests/unit/borg/test_mount.py | 6 +- tests/unit/borg/test_passcommand.py | 69 ++------- tests/unit/borg/test_prune.py | 4 +- tests/unit/borg/test_repo_create.py | 2 +- tests/unit/borg/test_repo_delete.py | 8 +- tests/unit/borg/test_repo_info.py | 50 +++--- tests/unit/borg/test_repo_list.py | 26 ++-- tests/unit/borg/test_transfer.py | 36 ++--- tests/unit/borg/test_version.py | 2 +- tests/unit/hooks/data_source/test_mariadb.py | 82 +++++----- tests/unit/hooks/data_source/test_mysql.py | 82 +++++----- .../unit/hooks/data_source/test_postgresql.py | 143 +++++++++--------- tests/unit/hooks/test_command.py | 12 +- tests/unit/test_execute.py | 70 +++------ 56 files changed, 561 insertions(+), 570 deletions(-) diff --git a/NEWS b/NEWS index b8370afa..dd0bd93f 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ * #795: Add credential loading from file, KeePassXC, and Docker/Podman secrets. See the documentation for more information: https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/ + * Send the "encryption_passphrase" option to Borg via an anonymous pipe, which is more secure than + using an environment variable. * Fix another error in the Btrfs hook when a subvolume mounted at "/" is configured in borgmatic's source directories. diff --git a/borgmatic/actions/check.py b/borgmatic/actions/check.py index d3e347e3..2fcca67d 100644 --- a/borgmatic/actions/check.py +++ b/borgmatic/actions/check.py @@ -391,7 +391,7 @@ def collect_spot_check_source_paths( paths_output = borgmatic.execute.execute_command_and_capture_output( create_flags + create_positional_arguments, capture_stderr=True, - extra_environment=borgmatic.borg.environment.make_environment(config), + environment=borgmatic.borg.environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/borg.py b/borgmatic/borg/borg.py index eb52894a..a2afd430 100644 --- a/borgmatic/borg/borg.py +++ b/borgmatic/borg/borg.py @@ -61,7 +61,7 @@ def run_arbitrary_borg( tuple(shlex.quote(part) for part in full_command), output_file=DO_NOT_CAPTURE, shell=True, - extra_environment=dict( + environment=dict( (environment.make_environment(config) or {}), **{ 'BORG_REPO': repository_path, diff --git a/borgmatic/borg/break_lock.py b/borgmatic/borg/break_lock.py index 478221f0..8c5533ce 100644 --- a/borgmatic/borg/break_lock.py +++ b/borgmatic/borg/break_lock.py @@ -36,7 +36,7 @@ def break_lock( execute_command( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/change_passphrase.py b/borgmatic/borg/change_passphrase.py index 79f9781d..f527e204 100644 --- a/borgmatic/borg/change_passphrase.py +++ b/borgmatic/borg/change_passphrase.py @@ -56,7 +56,7 @@ def change_passphrase( full_command, output_file=borgmatic.execute.DO_NOT_CAPTURE, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config_without_passphrase), + environment=environment.make_environment(config_without_passphrase), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/check.py b/borgmatic/borg/check.py index 4350b8e4..00a090a2 100644 --- a/borgmatic/borg/check.py +++ b/borgmatic/borg/check.py @@ -182,7 +182,7 @@ def check_archives( output_file=( DO_NOT_CAPTURE if check_arguments.repair or check_arguments.progress else None ), - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/compact.py b/borgmatic/borg/compact.py index eb16c6fa..fd248cbf 100644 --- a/borgmatic/borg/compact.py +++ b/borgmatic/borg/compact.py @@ -49,7 +49,7 @@ def compact_segments( execute_command( full_command, output_log_level=logging.INFO, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 924c50e7..9436afd4 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -143,7 +143,7 @@ def collect_special_file_paths( + ('--dry-run', '--list'), capture_stderr=True, working_directory=working_directory, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), ) @@ -409,7 +409,7 @@ def create_archive( output_log_level, output_file, working_directory=working_directory, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) @@ -417,7 +417,7 @@ def create_archive( return execute_command_and_capture_output( create_flags + create_positional_arguments, working_directory=working_directory, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) @@ -427,7 +427,7 @@ def create_archive( output_log_level, output_file, working_directory=working_directory, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), borg_local_path=local_path, borg_exit_codes=borg_exit_codes, ) diff --git a/borgmatic/borg/delete.py b/borgmatic/borg/delete.py index d53a1561..d967582c 100644 --- a/borgmatic/borg/delete.py +++ b/borgmatic/borg/delete.py @@ -128,7 +128,7 @@ def delete_archives( borgmatic.execute.execute_command( command, output_log_level=logging.ANSWER, - extra_environment=borgmatic.borg.environment.make_environment(config), + environment=borgmatic.borg.environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/environment.py b/borgmatic/borg/environment.py index 6e77552e..273fa91b 100644 --- a/borgmatic/borg/environment.py +++ b/borgmatic/borg/environment.py @@ -10,13 +10,10 @@ OPTION_TO_ENVIRONMENT_VARIABLE = { 'borg_files_cache_ttl': 'BORG_FILES_CACHE_TTL', 'borg_security_directory': 'BORG_SECURITY_DIR', 'borg_keys_directory': 'BORG_KEYS_DIR', - 'encryption_passphrase': 'BORG_PASSPHRASE', 'ssh_command': 'BORG_RSH', 'temporary_directory': 'TMPDIR', } -CREDENTIAL_OPTIONS = {'encryption_passphrase'} - DEFAULT_BOOL_OPTION_TO_DOWNCASE_ENVIRONMENT_VARIABLE = { 'relocated_repo_access_is_ok': 'BORG_RELOCATED_REPO_ACCESS_IS_OK', 'unknown_unencrypted_repo_access_is_ok': 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK', @@ -29,27 +26,49 @@ DEFAULT_BOOL_OPTION_TO_UPPERCASE_ENVIRONMENT_VARIABLE = { def make_environment(config): ''' - Given a borgmatic configuration dict, return its options converted to a Borg environment - variable dict. + Given a borgmatic configuration dict, convert it to a Borg environment variable dict, merge it + with a copy of the current environment variables and return the result. Do not reuse this environment across multiple Borg invocations, because it can include references to resources like anonymous pipes for passphrases—which can only be consumed once. + + Here's how native Borg precedence works for a few of the environment variables: + + 1. BORG_PASSPHRASE, if set, is used first. + 2. BORG_PASSCOMMAND is used only if BORG_PASSPHRASE isn't set. + 3. BORG_PASSPHRASE_FD is used only if neither of the above are set. + + In borgmatic, we want to simulate this precedence order, but there are some additional + complications. First, values can come from either configuration or from environment variables + set outside borgmatic and configured options should take precedence. Second, when borgmatic gets + a passphrase—directly from configuration or indirectly via a credential hook or a passcommand—we + want to pass that passphrase to Borg via an anonymous pipe (+ BORG_PASSPHRASE_FD), since that's + more secure than using an environment variable (BORG_PASSPHRASE). ''' - environment = {} + environment = dict(os.environ) for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items(): value = config.get(option_name) - if option_name in CREDENTIAL_OPTIONS and value is not None: - value = borgmatic.hooks.credential.parse.resolve_credential(value, config) - if value is not None: environment[environment_variable_name] = str(value) - passphrase = borgmatic.borg.passcommand.get_passphrase_from_passcommand(config) + if 'encryption_passphrase' in config: + environment.pop('BORG_PASSPHRASE', None) - # If the passcommand produced a passphrase, send it to Borg via an anonymous pipe. - if passphrase: + if 'encryption_passcommand' in config: + environment.pop('BORG_PASSCOMMAND', None) + + passphrase = borgmatic.hooks.credential.parse.resolve_credential( + config.get('encryption_passphrase'), config + ) + + if passphrase is None: + passphrase = borgmatic.borg.passcommand.get_passphrase_from_passcommand(config) + + # If there's a passphrase (from configuration, from a configured credential, or from a + # configured passcommand), send it to Borg via an anonymous pipe. + if passphrase is not None: read_file_descriptor, write_file_descriptor = os.pipe() os.write(write_file_descriptor, passphrase.encode('utf-8')) os.close(write_file_descriptor) diff --git a/borgmatic/borg/export_key.py b/borgmatic/borg/export_key.py index 768b52cc..0d050b16 100644 --- a/borgmatic/borg/export_key.py +++ b/borgmatic/borg/export_key.py @@ -67,7 +67,7 @@ def export_key( full_command, output_file=output_file, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/export_tar.py b/borgmatic/borg/export_tar.py index 728755d5..d8283535 100644 --- a/borgmatic/borg/export_tar.py +++ b/borgmatic/borg/export_tar.py @@ -70,7 +70,7 @@ def export_tar_archive( full_command, output_file=DO_NOT_CAPTURE if destination_path == '-' else None, output_log_level=output_log_level, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/extract.py b/borgmatic/borg/extract.py index d599b5b6..5097421c 100644 --- a/borgmatic/borg/extract.py +++ b/borgmatic/borg/extract.py @@ -58,7 +58,7 @@ def extract_last_archive_dry_run( execute_command( full_extract_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), @@ -154,7 +154,7 @@ def extract_archive( return execute_command( full_command, output_file=DO_NOT_CAPTURE, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=full_destination_path, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -166,7 +166,7 @@ def extract_archive( full_command, output_file=subprocess.PIPE, run_to_completion=False, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=full_destination_path, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -176,7 +176,7 @@ def extract_archive( # if the restore paths don't exist in the archive. execute_command( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=full_destination_path, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/info.py b/borgmatic/borg/info.py index 696048c4..bde80a97 100644 --- a/borgmatic/borg/info.py +++ b/borgmatic/borg/info.py @@ -102,7 +102,7 @@ def display_archives_info( json_info = execute_command_and_capture_output( json_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -116,7 +116,7 @@ def display_archives_info( execute_command( main_command, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/list.py b/borgmatic/borg/list.py index 755b05c9..fad36e77 100644 --- a/borgmatic/borg/list.py +++ b/borgmatic/borg/list.py @@ -124,7 +124,7 @@ def capture_archive_listing( local_path, remote_path, ), - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), @@ -221,7 +221,7 @@ def list_archive( local_path, remote_path, ), - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -257,7 +257,7 @@ def list_archive( execute_command( main_command, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/mount.py b/borgmatic/borg/mount.py index 06c6422c..627c42d3 100644 --- a/borgmatic/borg/mount.py +++ b/borgmatic/borg/mount.py @@ -66,7 +66,7 @@ def mount_archive( execute_command( full_command, output_file=DO_NOT_CAPTURE, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), @@ -75,7 +75,7 @@ def mount_archive( execute_command( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/passcommand.py b/borgmatic/borg/passcommand.py index f70a1392..79132fb4 100644 --- a/borgmatic/borg/passcommand.py +++ b/borgmatic/borg/passcommand.py @@ -9,21 +9,14 @@ logger = logging.getLogger(__name__) @functools.cache -def run_passcommand(passcommand, passphrase_configured, working_directory): +def run_passcommand(passcommand, working_directory): ''' Run the given passcommand using the given working directory and return the passphrase produced - by the command. But bail first if a passphrase is already configured; this mimics Borg's - behavior. + by the command. Cache the results so that the passcommand only needs to run—and potentially prompt the user—once per borgmatic invocation. ''' - if passcommand and passphrase_configured: - logger.warning( - 'Ignoring the "encryption_passcommand" option because "encryption_passphrase" is set' - ) - return None - return borgmatic.execute.execute_command_and_capture_output( shlex.split(passcommand), working_directory=working_directory, @@ -44,7 +37,4 @@ def get_passphrase_from_passcommand(config): if not passcommand: return None - passphrase = config.get('encryption_passphrase') - working_directory = borgmatic.config.paths.get_working_directory(config) - - return run_passcommand(passcommand, bool(passphrase is not None), working_directory) + return run_passcommand(passcommand, borgmatic.config.paths.get_working_directory(config)) diff --git a/borgmatic/borg/prune.py b/borgmatic/borg/prune.py index b9765fac..fa43d5e0 100644 --- a/borgmatic/borg/prune.py +++ b/borgmatic/borg/prune.py @@ -96,7 +96,7 @@ def prune_archives( execute_command( full_command, output_log_level=output_log_level, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/repo_create.py b/borgmatic/borg/repo_create.py index 7ccf85ba..b4cde394 100644 --- a/borgmatic/borg/repo_create.py +++ b/borgmatic/borg/repo_create.py @@ -98,7 +98,7 @@ def create_repository( execute_command( repo_create_command, output_file=DO_NOT_CAPTURE, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/repo_delete.py b/borgmatic/borg/repo_delete.py index e2241a3e..fa66d3c0 100644 --- a/borgmatic/borg/repo_delete.py +++ b/borgmatic/borg/repo_delete.py @@ -88,7 +88,7 @@ def delete_repository( if repo_delete_arguments.force or repo_delete_arguments.cache_only else borgmatic.execute.DO_NOT_CAPTURE ), - extra_environment=borgmatic.borg.environment.make_environment(config), + environment=borgmatic.borg.environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/repo_info.py b/borgmatic/borg/repo_info.py index 0c37a052..d3ea2575 100644 --- a/borgmatic/borg/repo_info.py +++ b/borgmatic/borg/repo_info.py @@ -56,7 +56,7 @@ def display_repository_info( if repo_info_arguments.json: return execute_command_and_capture_output( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -65,7 +65,7 @@ def display_repository_info( execute_command( full_command, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/repo_list.py b/borgmatic/borg/repo_list.py index f8e46289..9722758f 100644 --- a/borgmatic/borg/repo_list.py +++ b/borgmatic/borg/repo_list.py @@ -49,7 +49,7 @@ def resolve_archive_name( output = execute_command_and_capture_output( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), @@ -164,7 +164,7 @@ def list_repository( json_listing = execute_command_and_capture_output( json_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, @@ -178,7 +178,7 @@ def list_repository( execute_command( main_command, output_log_level=logging.ANSWER, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=working_directory, borg_local_path=local_path, borg_exit_codes=borg_exit_codes, diff --git a/borgmatic/borg/transfer.py b/borgmatic/borg/transfer.py index 473ae0cb..3af998a6 100644 --- a/borgmatic/borg/transfer.py +++ b/borgmatic/borg/transfer.py @@ -57,7 +57,7 @@ def transfer_archives( full_command, output_log_level=logging.ANSWER, output_file=DO_NOT_CAPTURE if transfer_arguments.progress else None, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/borg/version.py b/borgmatic/borg/version.py index e9cc4035..1c07dce6 100644 --- a/borgmatic/borg/version.py +++ b/borgmatic/borg/version.py @@ -21,7 +21,7 @@ def local_borg_version(config, local_path='borg'): ) output = execute_command_and_capture_output( full_command, - extra_environment=environment.make_environment(config), + environment=environment.make_environment(config), working_directory=borgmatic.config.paths.get_working_directory(config), borg_local_path=local_path, borg_exit_codes=config.get('borg_exit_codes'), diff --git a/borgmatic/execute.py b/borgmatic/execute.py index ca07458a..df58c833 100644 --- a/borgmatic/execute.py +++ b/borgmatic/execute.py @@ -1,7 +1,6 @@ import collections import enum import logging -import os import select import subprocess import textwrap @@ -243,6 +242,9 @@ def mask_command_secrets(full_command): MAX_LOGGED_COMMAND_LENGTH = 1000 +PREFIXES_OF_ENVIRONMENT_VARIABLES_TO_LOG = ('BORG_', 'PG', 'MARIADB_', 'MYSQL_') + + def log_command(full_command, input_file=None, output_file=None, environment=None): ''' Log the given command (a sequence of command/argument strings), along with its input/output file @@ -251,7 +253,14 @@ def log_command(full_command, input_file=None, output_file=None, environment=Non logger.debug( textwrap.shorten( ' '.join( - tuple(f'{key}=***' for key in (environment or {}).keys()) + tuple( + f'{key}=***' + for key in (environment or {}).keys() + if any( + key.startswith(prefix) + for prefix in PREFIXES_OF_ENVIRONMENT_VARIABLES_TO_LOG + ) + ) + mask_command_secrets(full_command) ), width=MAX_LOGGED_COMMAND_LENGTH, @@ -274,7 +283,7 @@ def execute_command( output_file=None, input_file=None, shell=False, - extra_environment=None, + environment=None, working_directory=None, borg_local_path=None, borg_exit_codes=None, @@ -284,18 +293,17 @@ def execute_command( Execute the given command (a sequence of command/argument strings) and log its output at the given log level. If an open output file object is given, then write stdout to the file and only log stderr. If an open input file object is given, then read stdin from the file. If shell is - True, execute the command within a shell. If an extra environment dict is given, then use it to - augment the current environment, and pass the result into the command. If a working directory is - given, use that as the present working directory when running the command. If a Borg local path - is given, and the command matches it (regardless of arguments), treat exit code 1 as a warning - instead of an error. But if Borg exit codes are given as a sequence of exit code configuration - dicts, then use that configuration to decide what's an error and what's a warning. If run to - completion is False, then return the process for the command without executing it to completion. + True, execute the command within a shell. If an environment variables dict is given, then pass + it into the command. If a working directory is given, use that as the present working directory + when running the command. If a Borg local path is given, and the command matches it (regardless + of arguments), treat exit code 1 as a warning instead of an error. But if Borg exit codes are + given as a sequence of exit code configuration dicts, then use that configuration to decide + what's an error and what's a warning. If run to completion is False, then return the process for + the command without executing it to completion. Raise subprocesses.CalledProcessError if an error occurs while running the command. ''' - log_command(full_command, input_file, output_file, extra_environment) - environment = {**os.environ, **extra_environment} if extra_environment else None + log_command(full_command, input_file, output_file, environment) do_not_capture = bool(output_file is DO_NOT_CAPTURE) command = ' '.join(full_command) if shell else full_command @@ -308,7 +316,7 @@ def execute_command( env=environment, cwd=working_directory, # Necessary for the passcommand credential hook to work. - close_fds=not bool((extra_environment or {}).get('BORG_PASSPHRASE_FD')), + close_fds=not bool((environment or {}).get('BORG_PASSPHRASE_FD')), ) if not run_to_completion: return process @@ -327,7 +335,7 @@ def execute_command_and_capture_output( full_command, capture_stderr=False, shell=False, - extra_environment=None, + environment=None, working_directory=None, borg_local_path=None, borg_exit_codes=None, @@ -335,18 +343,16 @@ def execute_command_and_capture_output( ''' Execute the given command (a sequence of command/argument strings), capturing and returning its output (stdout). If capture stderr is True, then capture and return stderr in addition to - stdout. If shell is True, execute the command within a shell. If an extra environment dict is - given, then use it to augment the current environment, and pass the result into the command. If - a working directory is given, use that as the present working directory when running the - command. If a Borg local path is given, and the command matches it (regardless of arguments), - treat exit code 1 as a warning instead of an error. But if Borg exit codes are given as a - sequence of exit code configuration dicts, then use that configuration to decide what's an error - and what's a warning. + stdout. If shell is True, execute the command within a shell. If an environment variables dict + is given, then pass it into the command. If a working directory is given, use that as the + present working directory when running the command. If a Borg local path is given, and the + command matches it (regardless of arguments), treat exit code 1 as a warning instead of an + error. But if Borg exit codes are given as a sequence of exit code configuration dicts, then use + that configuration to decide what's an error and what's a warning. Raise subprocesses.CalledProcessError if an error occurs while running the command. ''' - log_command(full_command, environment=extra_environment) - environment = {**os.environ, **extra_environment} if extra_environment else None + log_command(full_command, environment=environment) command = ' '.join(full_command) if shell else full_command try: @@ -357,7 +363,7 @@ def execute_command_and_capture_output( env=environment, cwd=working_directory, # Necessary for the passcommand credential hook to work. - close_fds=not bool((extra_environment or {}).get('BORG_PASSPHRASE_FD')), + close_fds=not bool((environment or {}).get('BORG_PASSPHRASE_FD')), ) except subprocess.CalledProcessError as error: if ( @@ -377,7 +383,7 @@ def execute_command_with_processes( output_file=None, input_file=None, shell=False, - extra_environment=None, + environment=None, working_directory=None, borg_local_path=None, borg_exit_codes=None, @@ -391,19 +397,17 @@ def execute_command_with_processes( If an open output file object is given, then write stdout to the file and only log stderr. But if output log level is None, instead suppress logging and return the captured output for (only) the given command. If an open input file object is given, then read stdin from the file. If - shell is True, execute the command within a shell. If an extra environment dict is given, then - use it to augment the current environment, and pass the result into the command. If a working - directory is given, use that as the present working directory when running the command. If a - Borg local path is given, then for any matching command or process (regardless of arguments), - treat exit code 1 as a warning instead of an error. But if Borg exit codes are given as a - sequence of exit code configuration dicts, then use that configuration to decide what's an error - and what's a warning. + shell is True, execute the command within a shell. If an environment variables dict is given, + then pass it into the command. If a working directory is given, use that as the present working + directory when running the command. If a Borg local path is given, then for any matching command + or process (regardless of arguments), treat exit code 1 as a warning instead of an error. But if + Borg exit codes are given as a sequence of exit code configuration dicts, then use that + configuration to decide what's an error and what's a warning. Raise subprocesses.CalledProcessError if an error occurs while running the command or in the upstream process. ''' - log_command(full_command, input_file, output_file, extra_environment) - environment = {**os.environ, **extra_environment} if extra_environment else None + log_command(full_command, input_file, output_file, environment) do_not_capture = bool(output_file is DO_NOT_CAPTURE) command = ' '.join(full_command) if shell else full_command @@ -419,7 +423,7 @@ def execute_command_with_processes( env=environment, cwd=working_directory, # Necessary for the passcommand credential hook to work. - close_fds=not bool((extra_environment or {}).get('BORG_PASSPHRASE_FD')), + close_fds=not bool((environment or {}).get('BORG_PASSPHRASE_FD')), ) except (subprocess.CalledProcessError, OSError): # Something has gone wrong. So vent each process' output buffer to prevent it from hanging. diff --git a/borgmatic/hooks/command.py b/borgmatic/hooks/command.py index d446ecca..9e605290 100644 --- a/borgmatic/hooks/command.py +++ b/borgmatic/hooks/command.py @@ -30,16 +30,18 @@ def interpolate_context(hook_description, command, context): def make_environment(current_environment, sys_module=sys): ''' - Given the existing system environment as a map from environment variable name to value, return - (in the same form) any extra environment variables that should be used when running command - hooks. + Given the existing system environment as a map from environment variable name to value, return a + copy of it, augmented with any extra environment variables that should be used when running + command hooks. ''' + environment = dict(current_environment) + # Detect whether we're running within a PyInstaller bundle. If so, set or clear LD_LIBRARY_PATH # based on the value of LD_LIBRARY_PATH_ORIG. This prevents library version information errors. if getattr(sys_module, 'frozen', False) and hasattr(sys_module, '_MEIPASS'): - return {'LD_LIBRARY_PATH': current_environment.get('LD_LIBRARY_PATH_ORIG', '')} + environment['LD_LIBRARY_PATH'] = environment.get('LD_LIBRARY_PATH_ORIG', '') - return {} + return environment def execute_hook(commands, umask, config_filename, description, dry_run, **context): @@ -85,7 +87,7 @@ def execute_hook(commands, umask, config_filename, description, dry_run, **conte [command], output_log_level=(logging.ERROR if description == 'on-error' else logging.WARNING), shell=True, - extra_environment=make_environment(os.environ), + environment=make_environment(os.environ), ) finally: if original_umask: diff --git a/borgmatic/hooks/data_source/mariadb.py b/borgmatic/hooks/data_source/mariadb.py index 47d1dfea..727932ee 100644 --- a/borgmatic/hooks/data_source/mariadb.py +++ b/borgmatic/hooks/data_source/mariadb.py @@ -26,7 +26,7 @@ def make_dump_path(base_directory): # pragma: no cover SYSTEM_DATABASE_NAMES = ('information_schema', 'mysql', 'performance_schema', 'sys') -def database_names_to_dump(database, config, extra_environment, dry_run): +def database_names_to_dump(database, config, environment, dry_run): ''' Given a requested database config and a configuration dict, return the corresponding sequence of database names to dump. In the case of "all", query for the names of databases on the configured @@ -58,9 +58,7 @@ def database_names_to_dump(database, config, extra_environment, dry_run): + ('--execute', 'show schemas') ) logger.debug('Querying for "all" MariaDB databases to dump') - show_output = execute_command_and_capture_output( - show_command, extra_environment=extra_environment - ) + show_output = execute_command_and_capture_output(show_command, environment=environment) return tuple( show_name @@ -70,7 +68,7 @@ def database_names_to_dump(database, config, extra_environment, dry_run): def execute_dump_command( - database, config, dump_path, database_names, extra_environment, dry_run, dry_run_label + database, config, dump_path, database_names, environment, dry_run, dry_run_label ): ''' Kick off a dump for the given MariaDB database (provided as a configuration dict) to a named @@ -125,7 +123,7 @@ def execute_dump_command( return execute_command( dump_command, - extra_environment=extra_environment, + environment=environment, run_to_completion=False, ) @@ -167,16 +165,19 @@ def dump_data_sources( for database in databases: dump_path = make_dump_path(borgmatic_runtime_directory) - extra_environment = ( - { - 'MYSQL_PWD': borgmatic.hooks.credential.parse.resolve_credential( - database['password'], config - ) - } - if 'password' in database - else None + environment = dict( + os.environ, + **( + { + 'MYSQL_PWD': borgmatic.hooks.credential.parse.resolve_credential( + database['password'], config + ) + } + if 'password' in database + else {} + ), ) - dump_database_names = database_names_to_dump(database, config, extra_environment, dry_run) + dump_database_names = database_names_to_dump(database, config, environment, dry_run) if not dump_database_names: if dry_run: @@ -194,7 +195,7 @@ def dump_data_sources( config, dump_path, (dump_name,), - extra_environment, + environment, dry_run, dry_run_label, ) @@ -206,7 +207,7 @@ def dump_data_sources( config, dump_path, dump_database_names, - extra_environment, + environment, dry_run, dry_run_label, ) @@ -307,7 +308,7 @@ def restore_data_source_dump( + (('--protocol', 'tcp') if hostname or port else ()) + (('--user', username) if username else ()) ) - extra_environment = {'MYSQL_PWD': password} if password else None + environment = dict(os.environ, **({'MYSQL_PWD': password} if password else {})) logger.debug(f"Restoring MariaDB database {data_source['name']}{dry_run_label}") if dry_run: @@ -320,5 +321,5 @@ def restore_data_source_dump( [extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=extra_environment, + environment=environment, ) diff --git a/borgmatic/hooks/data_source/mysql.py b/borgmatic/hooks/data_source/mysql.py index aa5a954e..ffa2bc3f 100644 --- a/borgmatic/hooks/data_source/mysql.py +++ b/borgmatic/hooks/data_source/mysql.py @@ -26,7 +26,7 @@ def make_dump_path(base_directory): # pragma: no cover SYSTEM_DATABASE_NAMES = ('information_schema', 'mysql', 'performance_schema', 'sys') -def database_names_to_dump(database, config, extra_environment, dry_run): +def database_names_to_dump(database, config, environment, dry_run): ''' Given a requested database config and a configuration dict, return the corresponding sequence of database names to dump. In the case of "all", query for the names of databases on the configured @@ -58,9 +58,7 @@ def database_names_to_dump(database, config, extra_environment, dry_run): + ('--execute', 'show schemas') ) logger.debug('Querying for "all" MySQL databases to dump') - show_output = execute_command_and_capture_output( - show_command, extra_environment=extra_environment - ) + show_output = execute_command_and_capture_output(show_command, environment=environment) return tuple( show_name @@ -70,7 +68,7 @@ def database_names_to_dump(database, config, extra_environment, dry_run): def execute_dump_command( - database, config, dump_path, database_names, extra_environment, dry_run, dry_run_label + database, config, dump_path, database_names, environment, dry_run, dry_run_label ): ''' Kick off a dump for the given MySQL/MariaDB database (provided as a configuration dict) to a @@ -124,7 +122,7 @@ def execute_dump_command( return execute_command( dump_command, - extra_environment=extra_environment, + environment=environment, run_to_completion=False, ) @@ -166,16 +164,19 @@ def dump_data_sources( for database in databases: dump_path = make_dump_path(borgmatic_runtime_directory) - extra_environment = ( - { - 'MYSQL_PWD': borgmatic.hooks.credential.parse.resolve_credential( - database['password'], config - ) - } - if 'password' in database - else None + environment = dict( + os.environ, + **( + { + 'MYSQL_PWD': borgmatic.hooks.credential.parse.resolve_credential( + database['password'], config + ) + } + if 'password' in database + else {} + ), ) - dump_database_names = database_names_to_dump(database, config, extra_environment, dry_run) + dump_database_names = database_names_to_dump(database, config, environment, dry_run) if not dump_database_names: if dry_run: @@ -193,7 +194,7 @@ def dump_data_sources( config, dump_path, (dump_name,), - extra_environment, + environment, dry_run, dry_run_label, ) @@ -205,7 +206,7 @@ def dump_data_sources( config, dump_path, dump_database_names, - extra_environment, + environment, dry_run, dry_run_label, ) @@ -306,7 +307,7 @@ def restore_data_source_dump( + (('--protocol', 'tcp') if hostname or port else ()) + (('--user', username) if username else ()) ) - extra_environment = {'MYSQL_PWD': password} if password else None + environment = dict(os.environ, **({'MYSQL_PWD': password} if password else {})) logger.debug(f"Restoring MySQL database {data_source['name']}{dry_run_label}") if dry_run: @@ -319,5 +320,5 @@ def restore_data_source_dump( [extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=extra_environment, + environment=environment, ) diff --git a/borgmatic/hooks/data_source/postgresql.py b/borgmatic/hooks/data_source/postgresql.py index a9eafea0..8cf17518 100644 --- a/borgmatic/hooks/data_source/postgresql.py +++ b/borgmatic/hooks/data_source/postgresql.py @@ -25,16 +25,16 @@ def make_dump_path(base_directory): # pragma: no cover return dump.make_data_source_dump_path(base_directory, 'postgresql_databases') -def make_extra_environment(database, config, restore_connection_params=None): +def make_environment(database, config, restore_connection_params=None): ''' - Make the extra_environment dict from the given database configuration. If restore connection - params are given, this is for a restore operation. + Make an environment dict from the current environment variables and the given database + configuration. If restore connection params are given, this is for a restore operation. ''' - extra = dict() + environment = dict(os.environ) try: if restore_connection_params: - extra['PGPASSWORD'] = borgmatic.hooks.credential.parse.resolve_credential( + environment['PGPASSWORD'] = borgmatic.hooks.credential.parse.resolve_credential( ( restore_connection_params.get('password') or database.get('restore_password', database['password']) @@ -42,30 +42,30 @@ def make_extra_environment(database, config, restore_connection_params=None): config, ) else: - extra['PGPASSWORD'] = borgmatic.hooks.credential.parse.resolve_credential( + environment['PGPASSWORD'] = borgmatic.hooks.credential.parse.resolve_credential( database['password'], config ) except (AttributeError, KeyError): pass if 'ssl_mode' in database: - extra['PGSSLMODE'] = database['ssl_mode'] + environment['PGSSLMODE'] = database['ssl_mode'] if 'ssl_cert' in database: - extra['PGSSLCERT'] = database['ssl_cert'] + environment['PGSSLCERT'] = database['ssl_cert'] if 'ssl_key' in database: - extra['PGSSLKEY'] = database['ssl_key'] + environment['PGSSLKEY'] = database['ssl_key'] if 'ssl_root_cert' in database: - extra['PGSSLROOTCERT'] = database['ssl_root_cert'] + environment['PGSSLROOTCERT'] = database['ssl_root_cert'] if 'ssl_crl' in database: - extra['PGSSLCRL'] = database['ssl_crl'] + environment['PGSSLCRL'] = database['ssl_crl'] - return extra + return environment EXCLUDED_DATABASE_NAMES = ('template0', 'template1') -def database_names_to_dump(database, config, extra_environment, dry_run): +def database_names_to_dump(database, config, environment, dry_run): ''' Given a requested database config and a configuration dict, return the corresponding sequence of database names to dump. In the case of "all" when a database format is given, query for the @@ -100,9 +100,7 @@ def database_names_to_dump(database, config, extra_environment, dry_run): + (tuple(database['list_options'].split(' ')) if 'list_options' in database else ()) ) logger.debug('Querying for "all" PostgreSQL databases to dump') - list_output = execute_command_and_capture_output( - list_command, extra_environment=extra_environment - ) + list_output = execute_command_and_capture_output(list_command, environment=environment) return tuple( row[0] @@ -149,9 +147,9 @@ def dump_data_sources( logger.info(f'Dumping PostgreSQL databases{dry_run_label}') for database in databases: - extra_environment = make_extra_environment(database, config) + environment = make_environment(database, config) dump_path = make_dump_path(borgmatic_runtime_directory) - dump_database_names = database_names_to_dump(database, config, extra_environment, dry_run) + dump_database_names = database_names_to_dump(database, config, environment, dry_run) if not dump_database_names: if dry_run: @@ -225,7 +223,7 @@ def dump_data_sources( execute_command( command, shell=True, - extra_environment=extra_environment, + environment=environment, ) else: dump.create_named_pipe_for_dump(dump_filename) @@ -233,7 +231,7 @@ def dump_data_sources( execute_command( command, shell=True, - extra_environment=extra_environment, + environment=environment, run_to_completion=False, ) ) @@ -369,9 +367,7 @@ def restore_data_source_dump( ) ) - extra_environment = make_extra_environment( - data_source, config, restore_connection_params=connection_params - ) + environment = make_environment(data_source, config, restore_connection_params=connection_params) logger.debug(f"Restoring PostgreSQL database {data_source['name']}{dry_run_label}") if dry_run: @@ -384,6 +380,6 @@ def restore_data_source_dump( [extract_process] if extract_process else [], output_log_level=logging.DEBUG, input_file=extract_process.stdout if extract_process else None, - extra_environment=extra_environment, + environment=environment, ) - execute_command(analyze_command, extra_environment=extra_environment) + execute_command(analyze_command, environment=environment) diff --git a/tests/unit/borg/test_borg.py b/tests/unit/borg/test_borg.py index 573ee21e..5f346917 100644 --- a/tests/unit/borg/test_borg.py +++ b/tests/unit/borg/test_borg.py @@ -17,7 +17,7 @@ def test_run_arbitrary_borg_calls_borg_with_flags(): ('borg', 'break-lock', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -41,7 +41,7 @@ def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_flag(): ('borg', 'break-lock', '--info', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -66,7 +66,7 @@ def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_flag(): ('borg', 'break-lock', '--debug', '--show-rc', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -94,7 +94,7 @@ def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_flags(): ('borg', 'break-lock', '--lock-wait', '5', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -118,7 +118,7 @@ def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_flag(): ('borg', 'break-lock', "'::$ARCHIVE'"), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': 'archive'}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': 'archive'}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -143,7 +143,7 @@ def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path(): ('borg1', 'break-lock', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg1', borg_exit_codes=None, @@ -169,7 +169,7 @@ def test_run_arbitrary_borg_with_exit_codes_calls_borg_using_them(): ('borg', 'break-lock', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -195,7 +195,7 @@ def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_flags() ('borg', 'break-lock', '--remote-path', 'borg1', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -222,7 +222,7 @@ def test_run_arbitrary_borg_with_remote_path_injection_attack_gets_escaped(): ('borg', 'break-lock', '--remote-path', "'borg1; naughty-command'", '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -247,7 +247,7 @@ def test_run_arbitrary_borg_passes_borg_specific_flags_to_borg(): ('borg', 'list', '--progress', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -271,7 +271,7 @@ def test_run_arbitrary_borg_omits_dash_dash_in_flags_passed_to_borg(): ('borg', 'break-lock', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -295,7 +295,7 @@ def test_run_arbitrary_borg_without_borg_specific_flags_does_not_raise(): ('borg',), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -319,7 +319,7 @@ def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_injected_flags ('borg', 'key', 'export', '--info', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -344,7 +344,7 @@ def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_injected_fla ('borg', 'debug', 'dump-manifest', '--info', '::', 'path'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -371,7 +371,7 @@ def test_run_arbitrary_borg_calls_borg_with_working_directory(): ('borg', 'break-lock', '::'), output_file=module.borgmatic.execute.DO_NOT_CAPTURE, shell=True, - extra_environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, + environment={'BORG_REPO': 'repo', 'ARCHIVE': ''}, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_break_lock.py b/tests/unit/borg/test_break_lock.py index 202cd7d6..8368a19a 100644 --- a/tests/unit/borg/test_break_lock.py +++ b/tests/unit/borg/test_break_lock.py @@ -14,7 +14,7 @@ def insert_execute_command_mock(command, working_directory=None, borg_exit_codes ) flexmock(module).should_receive('execute_command').with_args( command, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_change_passphrase.py b/tests/unit/borg/test_change_passphrase.py index c7b75c7c..ef4b7b35 100644 --- a/tests/unit/borg/test_change_passphrase.py +++ b/tests/unit/borg/test_change_passphrase.py @@ -25,7 +25,7 @@ def insert_execute_command_mock( command, output_file=output_file, output_log_level=module.logging.ANSWER, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_check.py b/tests/unit/borg/test_check.py index 3fadc2fd..cb3ce67c 100644 --- a/tests/unit/borg/test_check.py +++ b/tests/unit/borg/test_check.py @@ -18,7 +18,7 @@ def insert_execute_command_mock( flexmock(module).should_receive('execute_command').with_args( command, output_file=output_file, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, @@ -342,7 +342,7 @@ def test_check_archives_with_progress_passes_through_to_borg(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--progress', 'repo'), output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -377,7 +377,7 @@ def test_check_archives_with_repair_passes_through_to_borg(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--repair', 'repo'), output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -412,7 +412,7 @@ def test_check_archives_with_max_duration_flag_passes_through_to_borg(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--max-duration', '33', 'repo'), output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -447,7 +447,7 @@ def test_check_archives_with_max_duration_option_passes_through_to_borg(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--max-duration', '33', 'repo'), output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -610,7 +610,7 @@ def test_check_archives_with_max_duration_flag_overrides_max_duration_option(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--max-duration', '44', 'repo'), output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -963,7 +963,7 @@ def test_check_archives_with_match_archives_passes_through_to_borg(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'check', '--match-archives', 'foo-*', 'repo'), output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_compact.py b/tests/unit/borg/test_compact.py index 18df3d13..882dac69 100644 --- a/tests/unit/borg/test_compact.py +++ b/tests/unit/borg/test_compact.py @@ -17,7 +17,7 @@ def insert_execute_command_mock( flexmock(module).should_receive('execute_command').with_args( compact_command, output_log_level=output_log_level, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=compact_command[0], borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 6015004a..94e02425 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -296,7 +296,7 @@ def test_collect_special_file_paths_omits_exclude_no_dump_flag_from_command(): ('borg', 'create', '--dry-run', '--list'), capture_stderr=True, working_directory=None, - extra_environment=None, + environment=None, borg_local_path='borg', borg_exit_codes=None, ).and_return('Processing files ...\n- /foo\n+ /bar\n- /baz').once() @@ -969,7 +969,7 @@ def test_create_archive_calls_borg_with_parameters(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1003,7 +1003,7 @@ def test_create_archive_calls_borg_with_environment(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=environment, + environment=environment, ) module.create_archive( @@ -1036,7 +1036,7 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) insert_logging_mock(logging.INFO) @@ -1066,7 +1066,7 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'create', '--json') + REPO_ARCHIVE, working_directory=None, - extra_environment=None, + environment=None, borg_local_path='borg', borg_exit_codes=None, ) @@ -1103,7 +1103,7 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) insert_logging_mock(logging.DEBUG) @@ -1133,7 +1133,7 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'create', '--json') + REPO_ARCHIVE, working_directory=None, - extra_environment=None, + environment=None, borg_local_path='borg', borg_exit_codes=None, ) @@ -1172,7 +1172,7 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) insert_logging_mock(logging.INFO) @@ -1209,7 +1209,7 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory borg_local_path='borg', borg_exit_codes=None, working_directory='/working/dir', - extra_environment=None, + environment=None, ) module.create_archive( @@ -1244,7 +1244,7 @@ def test_create_archive_with_exit_codes_calls_borg_using_them(): borg_local_path='borg', borg_exit_codes=borg_exit_codes, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1278,7 +1278,7 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_answer_ou borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1316,7 +1316,7 @@ def test_create_archive_with_files_calls_borg_with_answer_output_log_level(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1350,7 +1350,7 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) insert_logging_mock(logging.INFO) @@ -1385,7 +1385,7 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter(): borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1431,7 +1431,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) flexmock(module).should_receive('execute_command_with_processes').with_args( create_command, @@ -1441,7 +1441,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr borg_local_path='borg', borg_exit_codes=None, working_directory=None, - extra_environment=None, + environment=None, ) module.create_archive( @@ -1472,7 +1472,7 @@ def test_create_archive_with_json_calls_borg_with_json_flag(): flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'create', '--json') + REPO_ARCHIVE, working_directory=None, - extra_environment=None, + environment=None, borg_local_path='borg', borg_exit_codes=None, ).and_return('[]') @@ -1506,7 +1506,7 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_flag(): flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'create', '--json') + REPO_ARCHIVE, working_directory=None, - extra_environment=None, + environment=None, borg_local_path='borg', borg_exit_codes=None, ).and_return('[]') @@ -1547,7 +1547,7 @@ def test_create_archive_calls_borg_with_working_directory(): borg_local_path='borg', borg_exit_codes=None, working_directory='/working/dir', - extra_environment=None, + environment=None, ) module.create_archive( diff --git a/tests/unit/borg/test_delete.py b/tests/unit/borg/test_delete.py index c3bf9db7..6d8614b6 100644 --- a/tests/unit/borg/test_delete.py +++ b/tests/unit/borg/test_delete.py @@ -370,9 +370,9 @@ def test_delete_archives_calls_borg_delete_with_working_directory(): flexmock(module.borgmatic.borg.repo_delete).should_receive('delete_repository').never() command = flexmock() flexmock(module).should_receive('make_delete_command').and_return(command) - extra_environment = flexmock() + environment = flexmock() flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( - extra_environment + environment ) flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working/dir' @@ -380,7 +380,7 @@ def test_delete_archives_calls_borg_delete_with_working_directory(): flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( command, output_log_level=logging.ANSWER, - extra_environment=extra_environment, + environment=environment, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index a63c3470..28ce3446 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -4,6 +4,7 @@ from borgmatic.borg import environment as module def test_make_environment_with_passcommand_should_call_it_and_set_passphrase_file_descriptor_in_environment(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return('passphrase') @@ -14,133 +15,148 @@ def test_make_environment_with_passcommand_should_call_it_and_set_passphrase_fil environment = module.make_environment({'encryption_passcommand': 'command'}) - assert not environment.get('BORG_PASSCOMMAND') + assert environment.get('BORG_PASSCOMMAND') is None assert environment.get('BORG_PASSPHRASE_FD') == '3' -def test_make_environment_with_passphrase_should_set_environment(): +def test_make_environment_with_passphrase_should_set_passphrase_file_descriptor_in_environment(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) - flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('pipe').and_return((3, 4)) + flexmock(module.os).should_receive('write') + flexmock(module.os).should_receive('close') + flexmock(module.os).should_receive('set_inheritable') environment = module.make_environment({'encryption_passphrase': 'pass'}) - assert environment.get('BORG_PASSPHRASE') == 'pass' + assert environment.get('BORG_PASSPHRASE') is None + assert environment.get('BORG_PASSPHRASE_FD') == '3' -def test_make_environment_with_credential_tag_passphrase_should_load_it_and_set_environment(): +def test_make_environment_with_credential_tag_passphrase_should_load_it_and_set_passphrase_file_descriptor_in_environment(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) config = {'encryption_passphrase': '{credential systemd pass}'} flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) - flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential', ).with_args('{credential systemd pass}', config).and_return('pass') + flexmock(module.os).should_receive('pipe').and_return((3, 4)) + flexmock(module.os).should_receive('write') + flexmock(module.os).should_receive('close') + flexmock(module.os).should_receive('set_inheritable') environment = module.make_environment(config) - assert environment.get('BORG_PASSPHRASE') == 'pass' + assert environment.get('BORG_PASSPHRASE') is None + assert environment.get('BORG_PASSPHRASE_FD') == '3' def test_make_environment_with_ssh_command_should_set_environment(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'ssh_command': 'ssh -C'}) assert environment.get('BORG_RSH') == 'ssh -C' def test_make_environment_without_configuration_sets_certain_environment_variables(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({}) # Default environment variables. assert environment == { + 'USER': 'root', 'BORG_EXIT_CODES': 'modern', 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no', 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no', } -def test_make_environment_without_configuration_does_not_set_certain_environment_variables_if_already_set(): +def test_make_environment_without_configuration_passes_through_default_environment_variables_untouched(): + flexmock(module.os).should_receive('environ').and_return( + { + 'USER': 'root', + 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'yup', + 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'nah', + } + ) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').with_args( - 'BORG_RELOCATED_REPO_ACCESS_IS_OK' - ).and_return('yup') - flexmock(module.os.environ).should_receive('get').with_args( - 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK' - ).and_return('nah') environment = module.make_environment({}) - assert environment == {'BORG_EXIT_CODES': 'modern'} + assert environment == { + 'USER': 'root', + 'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'yup', + 'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'nah', + 'BORG_EXIT_CODES': 'modern', + } def test_make_environment_with_relocated_repo_access_true_should_set_environment_yes(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'relocated_repo_access_is_ok': True}) assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes' def test_make_environment_with_relocated_repo_access_false_should_set_environment_no(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'relocated_repo_access_is_ok': False}) assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'no' def test_make_environment_check_i_know_what_i_am_doing_true_should_set_environment_YES(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'check_i_know_what_i_am_doing': True}) assert environment.get('BORG_CHECK_I_KNOW_WHAT_I_AM_DOING') == 'YES' def test_make_environment_check_i_know_what_i_am_doing_false_should_set_environment_NO(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'check_i_know_what_i_am_doing': False}) assert environment.get('BORG_CHECK_I_KNOW_WHAT_I_AM_DOING') == 'NO' def test_make_environment_with_integer_variable_value(): + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.borg.passcommand).should_receive( 'get_passphrase_from_passcommand' ).and_return(None) flexmock(module.os).should_receive('pipe').never() - flexmock(module.os.environ).should_receive('get').and_return(None) environment = module.make_environment({'borg_files_cache_ttl': 40}) assert environment.get('BORG_FILES_CACHE_TTL') == '40' diff --git a/tests/unit/borg/test_export_key.py b/tests/unit/borg/test_export_key.py index 2d7836a3..2fac04c2 100644 --- a/tests/unit/borg/test_export_key.py +++ b/tests/unit/borg/test_export_key.py @@ -22,7 +22,7 @@ def insert_execute_command_mock( command, output_file=output_file, output_log_level=module.logging.ANSWER, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_export_tar.py b/tests/unit/borg/test_export_tar.py index 53307127..f45026f3 100644 --- a/tests/unit/borg/test_export_tar.py +++ b/tests/unit/borg/test_export_tar.py @@ -23,7 +23,7 @@ def insert_execute_command_mock( command, output_file=None if capture else module.DO_NOT_CAPTURE, output_log_level=output_log_level, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=borg_local_path, borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_extract.py b/tests/unit/borg/test_extract.py index bddb2530..db244e54 100644 --- a/tests/unit/borg/test_extract.py +++ b/tests/unit/borg/test_extract.py @@ -12,7 +12,7 @@ def insert_execute_command_mock(command, destination_path=None, borg_exit_codes= flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( command, - extra_environment=None, + environment=None, working_directory=destination_path, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, @@ -587,7 +587,7 @@ def test_extract_archive_calls_borg_with_progress_parameter(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'extract', '--progress', 'repo::archive'), output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -639,7 +639,7 @@ def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process(): ('borg', 'extract', '--stdout', 'repo::archive'), output_file=module.subprocess.PIPE, run_to_completion=False, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -674,7 +674,7 @@ def test_extract_archive_skips_abspath_for_remote_repository(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command').with_args( ('borg', 'extract', 'server:repo::archive'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_info.py b/tests/unit/borg/test_info.py index e66f4911..5866b4ab 100644 --- a/tests/unit/borg/test_info.py +++ b/tests/unit/borg/test_info.py @@ -514,7 +514,7 @@ def test_display_archives_info_calls_borg_with_working_directory(): ) flexmock(module).should_receive('execute_command_and_capture_output').with_args( full_command=object, - extra_environment=object, + environment=object, working_directory='/working/dir', borg_local_path=object, borg_exit_codes=object, @@ -523,7 +523,7 @@ def test_display_archives_info_calls_borg_with_working_directory(): flexmock(module).should_receive('execute_command').with_args( full_command=object, output_log_level=object, - extra_environment=object, + environment=object, working_directory='/working/dir', borg_local_path=object, borg_exit_codes=object, diff --git a/tests/unit/borg/test_list.py b/tests/unit/borg/test_list.py index 26803c70..2268e8e5 100644 --- a/tests/unit/borg/test_list.py +++ b/tests/unit/borg/test_list.py @@ -353,7 +353,7 @@ def test_list_archive_calls_borg_with_flags(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -419,7 +419,7 @@ def test_list_archive_calls_borg_with_local_path(): flexmock(module).should_receive('execute_command').with_args( ('borg2', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg2', borg_exit_codes=None, @@ -469,7 +469,7 @@ def test_list_archive_calls_borg_using_exit_codes(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -507,7 +507,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -520,7 +520,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive1') + glob_paths, output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -528,7 +528,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive2') + glob_paths, output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -576,7 +576,7 @@ def test_list_archive_calls_borg_with_archive(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -699,7 +699,7 @@ def test_list_archive_with_archive_ignores_archive_filter_flag( flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -759,7 +759,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-list', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -808,7 +808,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--repo', 'repo', 'archive1') + glob_paths, output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -816,7 +816,7 @@ def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', '--repo', 'repo', 'archive2') + glob_paths, output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -875,7 +875,7 @@ def test_list_archive_calls_borg_with_working_directory(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'list', 'repo::archive'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_mount.py b/tests/unit/borg/test_mount.py index 46a92408..ee11f266 100644 --- a/tests/unit/borg/test_mount.py +++ b/tests/unit/borg/test_mount.py @@ -14,7 +14,7 @@ def insert_execute_command_mock(command, working_directory=None, borg_exit_codes ) flexmock(module).should_receive('execute_command').with_args( command, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=command[0], borg_exit_codes=borg_exit_codes, @@ -262,7 +262,7 @@ def test_mount_archive_calls_borg_with_foreground_parameter(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'mount', '--foreground', 'repo::archive', '/mnt'), output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -337,7 +337,7 @@ def test_mount_archive_with_date_based_matching_calls_borg_with_date_based_flags 'repo', '/mnt', ), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_passcommand.py b/tests/unit/borg/test_passcommand.py index 1a9a0e97..a6caea2e 100644 --- a/tests/unit/borg/test_passcommand.py +++ b/tests/unit/borg/test_passcommand.py @@ -3,26 +3,13 @@ from flexmock import flexmock from borgmatic.borg import passcommand as module -def test_run_passcommand_with_passphrase_configured_bails(): - module.run_passcommand.cache_clear() - flexmock(module.borgmatic.execute).should_receive('execute_command_and_capture_output').never() - - assert ( - module.run_passcommand('passcommand', passphrase_configured=True, working_directory=None) - is None - ) - - -def test_run_passcommand_without_passphrase_configured_executes_passcommand(): +def test_run_passcommand_does_not_raise(): module.run_passcommand.cache_clear() flexmock(module.borgmatic.execute).should_receive( 'execute_command_and_capture_output' - ).and_return('passphrase').once() + ).and_return('passphrase') - assert ( - module.run_passcommand('passcommand', passphrase_configured=False, working_directory=None) - == 'passphrase' - ) + assert module.run_passcommand('passcommand', working_directory=None) == 'passphrase' def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): @@ -30,9 +17,9 @@ def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working' ) - flexmock(module).should_receive('run_passcommand').with_args( - 'command', False, '/working' - ).and_return('passphrase').once() + flexmock(module).should_receive('run_passcommand').with_args('command', '/working').and_return( + 'passphrase' + ).once() assert ( module.get_passphrase_from_passcommand( @@ -42,38 +29,10 @@ def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): ) -def test_get_passphrase_from_passcommand_with_configured_passphrase_and_passcommand_detects_passphrase(): - module.run_passcommand.cache_clear() - flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working' - ) - flexmock(module).should_receive('run_passcommand').with_args( - 'command', True, '/working' - ).and_return(None).once() +def test_get_passphrase_from_passcommand_without_configured_passcommand_bails(): + flexmock(module).should_receive('run_passcommand').never() - assert ( - module.get_passphrase_from_passcommand( - {'encryption_passphrase': 'passphrase', 'encryption_passcommand': 'command'}, - ) - is None - ) - - -def test_get_passphrase_from_passcommand_with_configured_blank_passphrase_and_passcommand_detects_passphrase(): - module.run_passcommand.cache_clear() - flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( - '/working' - ) - flexmock(module).should_receive('run_passcommand').with_args( - 'command', True, '/working' - ).and_return(None).once() - - assert ( - module.get_passphrase_from_passcommand( - {'encryption_passphrase': '', 'encryption_passcommand': 'command'}, - ) - is None - ) + assert module.get_passphrase_from_passcommand({}) is None def test_run_passcommand_caches_passcommand_after_first_call(): @@ -82,11 +41,5 @@ def test_run_passcommand_caches_passcommand_after_first_call(): 'execute_command_and_capture_output' ).and_return('passphrase').once() - assert ( - module.run_passcommand('passcommand', passphrase_configured=False, working_directory=None) - == 'passphrase' - ) - assert ( - module.run_passcommand('passcommand', passphrase_configured=False, working_directory=None) - == 'passphrase' - ) + assert module.run_passcommand('passcommand', working_directory=None) == 'passphrase' + assert module.run_passcommand('passcommand', working_directory=None) == 'passphrase' diff --git a/tests/unit/borg/test_prune.py b/tests/unit/borg/test_prune.py index 4880f391..556d695f 100644 --- a/tests/unit/borg/test_prune.py +++ b/tests/unit/borg/test_prune.py @@ -17,7 +17,7 @@ def insert_execute_command_mock( flexmock(module).should_receive('execute_command').with_args( prune_command, output_log_level=output_log_level, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=prune_command[0], borg_exit_codes=borg_exit_codes, @@ -497,7 +497,7 @@ def test_prune_archives_with_date_based_matching_calls_borg_with_date_based_flag 'repo', ), output_log_level=logging.INFO, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_repo_create.py b/tests/unit/borg/test_repo_create.py index 388ebc7b..dc645f12 100644 --- a/tests/unit/borg/test_repo_create.py +++ b/tests/unit/borg/test_repo_create.py @@ -36,7 +36,7 @@ def insert_repo_create_command_mock( flexmock(module).should_receive('execute_command').with_args( repo_create_command, output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=repo_create_command[0], borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/borg/test_repo_delete.py b/tests/unit/borg/test_repo_delete.py index d490fa5d..66e73778 100644 --- a/tests/unit/borg/test_repo_delete.py +++ b/tests/unit/borg/test_repo_delete.py @@ -290,7 +290,7 @@ def test_delete_repository_with_defaults_does_not_capture_output(): command, output_log_level=module.logging.ANSWER, output_file=module.borgmatic.execute.DO_NOT_CAPTURE, - extra_environment=object, + environment=object, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -319,7 +319,7 @@ def test_delete_repository_with_force_captures_output(): command, output_log_level=module.logging.ANSWER, output_file=None, - extra_environment=object, + environment=object, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -348,7 +348,7 @@ def test_delete_repository_with_cache_only_captures_output(): command, output_log_level=module.logging.ANSWER, output_file=None, - extra_environment=object, + environment=object, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -379,7 +379,7 @@ def test_delete_repository_calls_borg_with_working_directory(): command, output_log_level=module.logging.ANSWER, output_file=module.borgmatic.execute.DO_NOT_CAPTURE, - extra_environment=object, + environment=object, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_repo_info.py b/tests/unit/borg/test_repo_info.py index 6a0cec11..555cb566 100644 --- a/tests/unit/borg/test_repo_info.py +++ b/tests/unit/borg/test_repo_info.py @@ -24,7 +24,7 @@ def test_display_repository_info_calls_borg_with_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -33,7 +33,7 @@ def test_display_repository_info_calls_borg_with_flags(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -60,7 +60,7 @@ def test_display_repository_info_without_borg_features_calls_borg_with_info_sub_ flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -69,7 +69,7 @@ def test_display_repository_info_without_borg_features_calls_borg_with_info_sub_ flexmock(module).should_receive('execute_command').with_args( ('borg', 'info', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -101,7 +101,7 @@ def test_display_repository_info_with_log_info_calls_borg_with_info_flag(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -110,7 +110,7 @@ def test_display_repository_info_with_log_info_calls_borg_with_info_flag(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -142,7 +142,7 @@ def test_display_repository_info_with_log_info_and_json_suppresses_most_borg_out flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -178,7 +178,7 @@ def test_display_repository_info_with_log_debug_calls_borg_with_debug_flag(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--debug', '--show-rc', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -187,7 +187,7 @@ def test_display_repository_info_with_log_debug_calls_borg_with_debug_flag(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--debug', '--show-rc', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -220,7 +220,7 @@ def test_display_repository_info_with_log_debug_and_json_suppresses_most_borg_ou flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -256,7 +256,7 @@ def test_display_repository_info_with_json_calls_borg_with_json_flag(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -291,7 +291,7 @@ def test_display_repository_info_with_local_path_calls_borg_via_local_path(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg1', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -300,7 +300,7 @@ def test_display_repository_info_with_local_path_calls_borg_via_local_path(): flexmock(module).should_receive('execute_command').with_args( ('borg1', 'repo-info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg1', borg_exit_codes=None, @@ -334,7 +334,7 @@ def test_display_repository_info_with_exit_codes_calls_borg_using_them(): borg_exit_codes = flexmock() flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -343,7 +343,7 @@ def test_display_repository_info_with_exit_codes_calls_borg_using_them(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -375,7 +375,7 @@ def test_display_repository_info_with_remote_path_calls_borg_with_remote_path_fl flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--remote-path', 'borg1', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -384,7 +384,7 @@ def test_display_repository_info_with_remote_path_calls_borg_with_remote_path_fl flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--remote-path', 'borg1', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -417,7 +417,7 @@ def test_display_repository_info_with_umask_calls_borg_with_umask_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--umask', '077', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -426,7 +426,7 @@ def test_display_repository_info_with_umask_calls_borg_with_umask_flags(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--umask', '077', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -462,7 +462,7 @@ def test_display_repository_info_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--log-json', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -471,7 +471,7 @@ def test_display_repository_info_with_log_json_calls_borg_with_log_json_flags(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--log-json', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -504,7 +504,7 @@ def test_display_repository_info_with_lock_wait_calls_borg_with_lock_wait_flags( flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--lock-wait', '5', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -513,7 +513,7 @@ def test_display_repository_info_with_lock_wait_calls_borg_with_lock_wait_flags( flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--lock-wait', '5', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -547,7 +547,7 @@ def test_display_repository_info_calls_borg_with_working_directory(): ) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'repo-info', '--json', '--repo', 'repo'), - extra_environment=None, + environment=None, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, @@ -556,7 +556,7 @@ def test_display_repository_info_calls_borg_with_working_directory(): flexmock(module).should_receive('execute_command').with_args( ('borg', 'repo-info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, - extra_environment=None, + environment=None, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_repo_list.py b/tests/unit/borg/test_repo_list.py index fec5e37e..da750d7a 100644 --- a/tests/unit/borg/test_repo_list.py +++ b/tests/unit/borg/test_repo_list.py @@ -39,7 +39,7 @@ def test_resolve_archive_name_calls_borg_with_flags(): ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, borg_local_path='borg', borg_exit_codes=None, - extra_environment=None, + environment=None, working_directory=None, ).and_return(expected_archive + '\n') @@ -61,7 +61,7 @@ def test_resolve_archive_name_with_log_info_calls_borg_without_info_flag(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -86,7 +86,7 @@ def test_resolve_archive_name_with_log_debug_calls_borg_without_debug_flag(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -111,7 +111,7 @@ def test_resolve_archive_name_with_local_path_calls_borg_via_local_path(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg1', 'list') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg1', borg_exit_codes=None, @@ -137,7 +137,7 @@ def test_resolve_archive_name_with_exit_codes_calls_borg_using_them(): borg_exit_codes = flexmock() flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -161,7 +161,7 @@ def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_flags flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list', '--remote-path', 'borg1') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -186,7 +186,7 @@ def test_resolve_archive_name_with_umask_calls_borg_with_umask_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list', '--umask', '077') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -209,7 +209,7 @@ def test_resolve_archive_name_without_archives_raises(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -232,7 +232,7 @@ def test_resolve_archive_name_with_log_json_calls_borg_with_log_json_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list', '--log-json') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -257,7 +257,7 @@ def test_resolve_archive_name_with_lock_wait_calls_borg_with_lock_wait_flags(): flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('borg', 'list', '--lock-wait', 'okay') + BORG_LIST_LATEST_ARGUMENTS, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -285,7 +285,7 @@ def test_resolve_archive_name_calls_borg_with_working_directory(): ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, borg_local_path='borg', borg_exit_codes=None, - extra_environment=None, + environment=None, working_directory='/working/dir', ).and_return(expected_archive + '\n') @@ -773,7 +773,7 @@ def test_list_repository_calls_borg_with_working_directory(): ) flexmock(module).should_receive('execute_command_and_capture_output').with_args( full_command=object, - extra_environment=object, + environment=object, working_directory='/working/dir', borg_local_path=object, borg_exit_codes=object, @@ -782,7 +782,7 @@ def test_list_repository_calls_borg_with_working_directory(): flexmock(module).should_receive('execute_command').with_args( full_command=object, output_log_level=object, - extra_environment=object, + environment=object, working_directory='/working/dir', borg_local_path=object, borg_exit_codes=object, diff --git a/tests/unit/borg/test_transfer.py b/tests/unit/borg/test_transfer.py index 49514861..edd2131b 100644 --- a/tests/unit/borg/test_transfer.py +++ b/tests/unit/borg/test_transfer.py @@ -21,7 +21,7 @@ def test_transfer_archives_calls_borg_with_flags(): ('borg', 'transfer', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -55,7 +55,7 @@ def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag(): ('borg', 'transfer', '--repo', 'repo', '--dry-run'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -86,7 +86,7 @@ def test_transfer_archives_with_log_info_calls_borg_with_info_flag(): ('borg', 'transfer', '--info', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -117,7 +117,7 @@ def test_transfer_archives_with_log_debug_calls_borg_with_debug_flag(): ('borg', 'transfer', '--debug', '--show-rc', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -151,7 +151,7 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag(): ('borg', 'transfer', '--match-archives', 'archive', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -184,7 +184,7 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl ('borg', 'transfer', '--match-archives', 'sh:foo*', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -217,7 +217,7 @@ def test_transfer_archives_with_archive_name_format_calls_borg_with_match_archiv ('borg', 'transfer', '--match-archives', 'sh:bar-*', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -248,7 +248,7 @@ def test_transfer_archives_with_local_path_calls_borg_via_local_path(): ('borg2', 'transfer', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg2', borg_exit_codes=None, @@ -281,7 +281,7 @@ def test_transfer_archives_with_exit_codes_calls_borg_using_them(): ('borg', 'transfer', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=borg_exit_codes, @@ -315,7 +315,7 @@ def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags(): ('borg', 'transfer', '--remote-path', 'borg2', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -349,7 +349,7 @@ def test_transfer_archives_with_umask_calls_borg_with_umask_flags(): ('borg', 'transfer', '--umask', '077', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -383,7 +383,7 @@ def test_transfer_archives_with_log_json_calls_borg_with_log_json_flags(): ('borg', 'transfer', '--log-json', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -418,7 +418,7 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags(): ('borg', 'transfer', '--lock-wait', '5', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -449,7 +449,7 @@ def test_transfer_archives_with_progress_calls_borg_with_progress_flag(): ('borg', 'transfer', '--progress', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=module.DO_NOT_CAPTURE, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -484,7 +484,7 @@ def test_transfer_archives_passes_through_arguments_to_borg(argument_name): ('borg', 'transfer', flag_name, 'value', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -521,7 +521,7 @@ def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_fla ('borg', 'transfer', '--repo', 'repo', '--other-repo', 'other'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -566,7 +566,7 @@ def test_transfer_archives_with_date_based_matching_calls_borg_with_date_based_f ), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory=None, borg_local_path='borg', borg_exit_codes=None, @@ -605,7 +605,7 @@ def test_transfer_archives_calls_borg_with_working_directory(): ('borg', 'transfer', '--repo', 'repo'), output_log_level=module.borgmatic.logger.ANSWER, output_file=None, - extra_environment=None, + environment=None, working_directory='/working/dir', borg_local_path='borg', borg_exit_codes=None, diff --git a/tests/unit/borg/test_version.py b/tests/unit/borg/test_version.py index 383eff55..17fc1861 100644 --- a/tests/unit/borg/test_version.py +++ b/tests/unit/borg/test_version.py @@ -23,7 +23,7 @@ def insert_execute_command_and_capture_output_mock( ) flexmock(module).should_receive('execute_command_and_capture_output').with_args( command, - extra_environment=None, + environment=None, working_directory=working_directory, borg_local_path=borg_local_path, borg_exit_codes=borg_exit_codes, diff --git a/tests/unit/hooks/data_source/test_mariadb.py b/tests/unit/hooks/data_source/test_mariadb.py index 30209f51..474c7d6d 100644 --- a/tests/unit/hooks/data_source/test_mariadb.py +++ b/tests/unit/hooks/data_source/test_mariadb.py @@ -7,33 +7,33 @@ from borgmatic.hooks.data_source import mariadb as module def test_database_names_to_dump_passes_through_name(): - extra_environment = flexmock() + environment = flexmock() - names = module.database_names_to_dump({'name': 'foo'}, {}, extra_environment, dry_run=False) + names = module.database_names_to_dump({'name': 'foo'}, {}, environment, dry_run=False) assert names == ('foo',) def test_database_names_to_dump_bails_for_dry_run(): - extra_environment = flexmock() + environment = flexmock() flexmock(module).should_receive('execute_command_and_capture_output').never() - names = module.database_names_to_dump({'name': 'all'}, {}, extra_environment, dry_run=True) + names = module.database_names_to_dump({'name': 'all'}, {}, environment, dry_run=True) assert names == () def test_database_names_to_dump_queries_mariadb_for_database_names(): - extra_environment = flexmock() + environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('mariadb', '--skip-column-names', '--batch', '--execute', 'show schemas'), - extra_environment=extra_environment, + environment=environment, ).and_return('foo\nbar\nmysql\n').once() - names = module.database_names_to_dump({'name': 'all'}, {}, extra_environment, dry_run=False) + names = module.database_names_to_dump({'name': 'all'}, {}, environment, dry_run=False) assert names == ('foo', 'bar') @@ -53,6 +53,7 @@ def test_dump_data_sources_dumps_each_database(): databases = [{'name': 'foo'}, {'name': 'bar'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -66,7 +67,7 @@ def test_dump_data_sources_dumps_each_database(): config={}, dump_path=object, database_names=(name,), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -88,6 +89,7 @@ def test_dump_data_sources_dumps_with_password(): database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'} process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -100,7 +102,7 @@ def test_dump_data_sources_dumps_with_password(): config={}, dump_path=object, database_names=('foo',), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -119,6 +121,7 @@ def test_dump_data_sources_dumps_all_databases_at_once(): databases = [{'name': 'all'}] process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -128,7 +131,7 @@ def test_dump_data_sources_dumps_all_databases_at_once(): config={}, dump_path=object, database_names=('foo', 'bar'), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -147,6 +150,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured databases = [{'name': 'all', 'format': 'sql'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -158,7 +162,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured config={}, dump_path=object, database_names=(name,), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -187,7 +191,7 @@ def test_database_names_to_dump_runs_mariadb_with_list_options(): '--execute', 'show schemas', ), - extra_environment=None, + environment=None, ).and_return(('foo\nbar')).once() assert module.database_names_to_dump(database, {}, None, '') == ('foo', 'bar') @@ -200,7 +204,7 @@ def test_database_names_to_dump_runs_non_default_mariadb_with_list_options(): 'mariadb_command': 'custom_mariadb', } flexmock(module).should_receive('execute_command_and_capture_output').with_args( - extra_environment=None, + environment=None, full_command=( 'custom_mariadb', # Custom MariaDB command '--defaults-extra-file=mariadb.cnf', @@ -232,7 +236,7 @@ def test_execute_dump_command_runs_mariadb_dump(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -242,7 +246,7 @@ def test_execute_dump_command_runs_mariadb_dump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -267,7 +271,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -277,7 +281,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -309,7 +313,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -319,7 +323,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -347,7 +351,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password(): '--result-file', 'dump', ), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'MYSQL_PWD': 'trustsome1'}, run_to_completion=False, ).and_return(process).once() @@ -357,7 +361,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'MYSQL_PWD': 'trustsome1'}, dry_run=False, dry_run_label='', ) @@ -384,7 +388,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_options(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -394,7 +398,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_options(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -421,7 +425,7 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -435,7 +439,7 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -455,7 +459,7 @@ def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=True, dry_run_label='SO DRY', ) @@ -479,7 +483,7 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=True, dry_run_label='SO DRY', ) @@ -490,6 +494,7 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump(): def test_dump_data_sources_errors_for_missing_all_databases(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -512,6 +517,7 @@ def test_dump_data_sources_errors_for_missing_all_databases(): def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -540,12 +546,13 @@ def test_restore_data_source_dump_runs_mariadb_to_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -571,12 +578,13 @@ def test_restore_data_source_dump_runs_mariadb_with_options(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch', '--harder'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -604,12 +612,13 @@ def test_restore_data_source_dump_runs_non_default_mariadb_with_options(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('custom_mariadb', '--batch', '--harder'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -635,6 +644,7 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -649,7 +659,7 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -675,12 +685,13 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch', '--user', 'root'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, ).once() module.restore_data_source_dump( @@ -716,6 +727,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -732,7 +744,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'clipassword'}, + environment={'USER': 'root', 'MYSQL_PWD': 'clipassword'}, ).once() module.restore_data_source_dump( @@ -770,6 +782,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -786,7 +799,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'restorepass'}, + environment={'USER': 'root', 'MYSQL_PWD': 'restorepass'}, ).once() module.restore_data_source_dump( @@ -811,6 +824,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').never() module.restore_data_source_dump( diff --git a/tests/unit/hooks/data_source/test_mysql.py b/tests/unit/hooks/data_source/test_mysql.py index 3fcf43eb..5b4cbcc9 100644 --- a/tests/unit/hooks/data_source/test_mysql.py +++ b/tests/unit/hooks/data_source/test_mysql.py @@ -7,36 +7,36 @@ from borgmatic.hooks.data_source import mysql as module def test_database_names_to_dump_passes_through_name(): - extra_environment = flexmock() + environment = flexmock() - names = module.database_names_to_dump({'name': 'foo'}, {}, extra_environment, dry_run=False) + names = module.database_names_to_dump({'name': 'foo'}, {}, environment, dry_run=False) assert names == ('foo',) def test_database_names_to_dump_bails_for_dry_run(): - extra_environment = flexmock() + environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').never() - names = module.database_names_to_dump({'name': 'all'}, {}, extra_environment, dry_run=True) + names = module.database_names_to_dump({'name': 'all'}, {}, environment, dry_run=True) assert names == () def test_database_names_to_dump_queries_mysql_for_database_names(): - extra_environment = flexmock() + environment = flexmock() flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('mysql', '--skip-column-names', '--batch', '--execute', 'show schemas'), - extra_environment=extra_environment, + environment=environment, ).and_return('foo\nbar\nmysql\n').once() - names = module.database_names_to_dump({'name': 'all'}, {}, extra_environment, dry_run=False) + names = module.database_names_to_dump({'name': 'all'}, {}, environment, dry_run=False) assert names == ('foo', 'bar') @@ -56,6 +56,7 @@ def test_dump_data_sources_dumps_each_database(): databases = [{'name': 'foo'}, {'name': 'bar'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) ) @@ -66,7 +67,7 @@ def test_dump_data_sources_dumps_each_database(): config={}, dump_path=object, database_names=(name,), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -88,6 +89,7 @@ def test_dump_data_sources_dumps_with_password(): database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'} process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -100,7 +102,7 @@ def test_dump_data_sources_dumps_with_password(): config={}, dump_path=object, database_names=('foo',), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -119,13 +121,14 @@ def test_dump_data_sources_dumps_all_databases_at_once(): databases = [{'name': 'all'}] process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) flexmock(module).should_receive('execute_dump_command').with_args( database={'name': 'all'}, config={}, dump_path=object, database_names=('foo', 'bar'), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -144,6 +147,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured databases = [{'name': 'all', 'format': 'sql'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) for name, process in zip(('foo', 'bar'), processes): @@ -152,7 +156,7 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured config={}, dump_path=object, database_names=(name,), - extra_environment=object, + environment={'USER': 'root'}, dry_run=object, dry_run_label=object, ).and_return(process).once() @@ -181,7 +185,7 @@ def test_database_names_to_dump_runs_mysql_with_list_options(): '--execute', 'show schemas', ), - extra_environment=None, + environment=None, ).and_return(('foo\nbar')).once() assert module.database_names_to_dump(database, {}, None, '') == ('foo', 'bar') @@ -194,7 +198,7 @@ def test_database_names_to_dump_runs_non_default_mysql_with_list_options(): 'mysql_command': 'custom_mysql', } flexmock(module).should_receive('execute_command_and_capture_output').with_args( - extra_environment=None, + environment=None, full_command=( 'custom_mysql', # Custom MySQL command '--defaults-extra-file=my.cnf', @@ -226,7 +230,7 @@ def test_execute_dump_command_runs_mysqldump(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -236,7 +240,7 @@ def test_execute_dump_command_runs_mysqldump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -261,7 +265,7 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -271,7 +275,7 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -303,7 +307,7 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -313,7 +317,7 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -341,7 +345,7 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password(): '--result-file', 'dump', ), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'MYSQL_PWD': 'trustsome1'}, run_to_completion=False, ).and_return(process).once() @@ -351,7 +355,7 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'MYSQL_PWD': 'trustsome1'}, dry_run=False, dry_run_label='', ) @@ -378,7 +382,7 @@ def test_execute_dump_command_runs_mysqldump_with_options(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -388,7 +392,7 @@ def test_execute_dump_command_runs_mysqldump_with_options(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -414,7 +418,7 @@ def test_execute_dump_command_runs_non_default_mysqldump(): '--result-file', 'dump', ), - extra_environment=None, + environment=None, run_to_completion=False, ).and_return(process).once() @@ -427,7 +431,7 @@ def test_execute_dump_command_runs_non_default_mysqldump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=False, dry_run_label='', ) @@ -447,7 +451,7 @@ def test_execute_dump_command_with_duplicate_dump_skips_mysqldump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=True, dry_run_label='SO DRY', ) @@ -471,7 +475,7 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump(): config={}, dump_path=flexmock(), database_names=('foo',), - extra_environment=None, + environment=None, dry_run=True, dry_run_label='SO DRY', ) @@ -482,6 +486,7 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump(): def test_dump_data_sources_errors_for_missing_all_databases(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -504,6 +509,7 @@ def test_dump_data_sources_errors_for_missing_all_databases(): def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) @@ -532,12 +538,13 @@ def test_restore_data_source_dump_runs_mysql_to_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -563,12 +570,13 @@ def test_restore_data_source_dump_runs_mysql_with_options(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch', '--harder'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -594,12 +602,13 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('custom_mysql', '--batch', '--harder'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -625,6 +634,7 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -639,7 +649,7 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment=None, + environment={'USER': 'root'}, ).once() module.restore_data_source_dump( @@ -665,12 +675,13 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch', '--user', 'root'), processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'trustsome1'}, + environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'}, ).once() module.restore_data_source_dump( @@ -706,6 +717,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -722,7 +734,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'clipassword'}, + environment={'USER': 'root', 'MYSQL_PWD': 'clipassword'}, ).once() module.restore_data_source_dump( @@ -760,6 +772,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -776,7 +789,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'MYSQL_PWD': 'restorepass'}, + environment={'USER': 'root', 'MYSQL_PWD': 'restorepass'}, ).once() module.restore_data_source_dump( @@ -801,6 +814,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module).should_receive('execute_command_with_processes').never() module.restore_data_source_dump( diff --git a/tests/unit/hooks/data_source/test_postgresql.py b/tests/unit/hooks/data_source/test_postgresql.py index 6bdf083c..1037cf66 100644 --- a/tests/unit/hooks/data_source/test_postgresql.py +++ b/tests/unit/hooks/data_source/test_postgresql.py @@ -6,7 +6,7 @@ from flexmock import flexmock from borgmatic.hooks.data_source import postgresql as module -def test_make_extra_environment_maps_options_to_environment(): +def test_make_environment_maps_options_to_environment(): database = { 'name': 'foo', 'password': 'pass', @@ -17,6 +17,7 @@ def test_make_extra_environment_maps_options_to_environment(): 'ssl_crl': 'crl.crl', } expected = { + 'USER': 'root', 'PGPASSWORD': 'pass', 'PGSSLMODE': 'require', 'PGSSLCERT': 'cert.crt', @@ -24,44 +25,44 @@ def test_make_extra_environment_maps_options_to_environment(): 'PGSSLROOTCERT': 'root.crt', 'PGSSLCRL': 'crl.crl', } + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - extra_env = module.make_extra_environment(database, {}) - - assert extra_env == expected + assert module.make_environment(database, {}) == expected -def test_make_extra_environment_with_cli_password_sets_correct_password(): +def test_make_environment_with_cli_password_sets_correct_password(): database = {'name': 'foo', 'restore_password': 'trustsome1', 'password': 'anotherpassword'} + flexmock(module.os).should_receive('environ').and_return({'USER': 'root'}) flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - extra = module.make_extra_environment( + environment = module.make_environment( database, {}, restore_connection_params={'password': 'clipassword'} ) - assert extra['PGPASSWORD'] == 'clipassword' + assert environment['PGPASSWORD'] == 'clipassword' -def test_make_extra_environment_without_cli_password_or_configured_password_does_not_set_password(): +def test_make_environment_without_cli_password_or_configured_password_does_not_set_password(): database = {'name': 'foo'} - extra = module.make_extra_environment( + environment = module.make_environment( database, {}, restore_connection_params={'username': 'someone'} ) - assert 'PGPASSWORD' not in extra + assert 'PGPASSWORD' not in environment -def test_make_extra_environment_without_ssl_mode_does_not_set_ssl_mode(): +def test_make_environment_without_ssl_mode_does_not_set_ssl_mode(): database = {'name': 'foo'} - extra = module.make_extra_environment(database, {}) + environment = module.make_environment(database, {}) - assert 'PGSSLMODE' not in extra + assert 'PGSSLMODE' not in environment def test_database_names_to_dump_passes_through_individual_database_name(): @@ -125,7 +126,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostnam '--port', '1234', ), - extra_environment=object, + environment=object, ).and_return('foo,test,\nbar,test,"stuff and such"') assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ( @@ -150,7 +151,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam '--username', 'postgres', ), - extra_environment=object, + environment=object, ).and_return('foo,test,\nbar,test,"stuff and such"') assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ( @@ -166,7 +167,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_options ).replace_with(lambda value, config: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('psql', '--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only', '--harder'), - extra_environment=object, + environment=object, ).and_return('foo,test,\nbar,test,"stuff and such"') assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ( @@ -210,7 +211,7 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command(): '--csv', '--tuples-only', ), - extra_environment=object, + environment=object, ).and_return('foo,text').once() assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ('foo',) @@ -237,7 +238,7 @@ def test_use_streaming_false_for_no_databases(): def test_dump_data_sources_runs_pg_dump_for_each_database(): databases = [{'name': 'foo'}, {'name': 'bar'}] processes = [flexmock(), flexmock()] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) @@ -265,7 +266,7 @@ def test_dump_data_sources_runs_pg_dump_for_each_database(): f'databases/localhost/{name}', ), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -284,7 +285,7 @@ def test_dump_data_sources_runs_pg_dump_for_each_database(): def test_dump_data_sources_raises_when_no_database_names_to_dump(): databases = [{'name': 'foo'}, {'name': 'bar'}] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -301,7 +302,7 @@ def test_dump_data_sources_raises_when_no_database_names_to_dump(): def test_dump_data_sources_does_not_raise_when_no_database_names_to_dump(): databases = [{'name': 'foo'}, {'name': 'bar'}] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(()) @@ -317,7 +318,7 @@ def test_dump_data_sources_does_not_raise_when_no_database_names_to_dump(): def test_dump_data_sources_with_duplicate_dump_skips_pg_dump(): databases = [{'name': 'foo'}, {'name': 'bar'}] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) @@ -344,7 +345,7 @@ def test_dump_data_sources_with_duplicate_dump_skips_pg_dump(): def test_dump_data_sources_with_dry_run_skips_pg_dump(): databases = [{'name': 'foo'}, {'name': 'bar'}] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) @@ -375,7 +376,7 @@ def test_dump_data_sources_with_dry_run_skips_pg_dump(): def test_dump_data_sources_runs_pg_dump_with_hostname_and_port(): databases = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( @@ -404,7 +405,7 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port(): 'databases/database.example.org/foo', ), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -421,7 +422,7 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port(): def test_dump_data_sources_runs_pg_dump_with_username_and_password(): databases = [{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1'}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return( + flexmock(module).should_receive('make_environment').and_return( {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} ) flexmock(module).should_receive('make_dump_path').and_return('') @@ -450,7 +451,7 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password(): 'databases/localhost/foo', ), shell=True, - extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -467,7 +468,7 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password(): def test_dump_data_sources_with_username_injection_attack_gets_escaped(): databases = [{'name': 'foo', 'username': 'postgres; naughty-command', 'password': 'trustsome1'}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return( + flexmock(module).should_receive('make_environment').and_return( {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} ) flexmock(module).should_receive('make_dump_path').and_return('') @@ -496,7 +497,7 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped(): 'databases/localhost/foo', ), shell=True, - extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -512,7 +513,7 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped(): def test_dump_data_sources_runs_pg_dump_with_directory_format(): databases = [{'name': 'foo', 'format': 'directory'}] - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( @@ -538,7 +539,7 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format(): 'foo', ), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).and_return(flexmock()).once() assert ( @@ -557,7 +558,7 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format(): def test_dump_data_sources_runs_pg_dump_with_options(): databases = [{'name': 'foo', 'options': '--stuff=such'}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( @@ -583,7 +584,7 @@ def test_dump_data_sources_runs_pg_dump_with_options(): 'databases/localhost/foo', ), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -600,7 +601,7 @@ def test_dump_data_sources_runs_pg_dump_with_options(): def test_dump_data_sources_runs_pg_dumpall_for_all_databases(): databases = [{'name': 'all'}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('all',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( @@ -615,7 +616,7 @@ def test_dump_data_sources_runs_pg_dumpall_for_all_databases(): flexmock(module).should_receive('execute_command').with_args( ('pg_dumpall', '--no-password', '--clean', '--if-exists', '>', 'databases/localhost/all'), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -632,7 +633,7 @@ def test_dump_data_sources_runs_pg_dumpall_for_all_databases(): def test_dump_data_sources_runs_non_default_pg_dump(): databases = [{'name': 'foo', 'pg_dump_command': 'special_pg_dump --compress *'}] process = flexmock() - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path').and_return('') flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( @@ -659,7 +660,7 @@ def test_dump_data_sources_runs_non_default_pg_dump(): 'databases/localhost/foo', ), shell=True, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, run_to_completion=False, ).and_return(process).once() @@ -680,7 +681,7 @@ def test_restore_data_source_dump_runs_pg_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -696,7 +697,7 @@ def test_restore_data_source_dump_runs_pg_restore(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -709,7 +710,7 @@ def test_restore_data_source_dump_runs_pg_restore(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -737,7 +738,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -757,7 +758,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -774,7 +775,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -802,7 +803,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return( + flexmock(module).should_receive('make_environment').and_return( {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} ) flexmock(module).should_receive('make_dump_path') @@ -822,7 +823,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -837,7 +838,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password(): '--command', 'ANALYZE', ), - extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -876,7 +877,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return( + flexmock(module).should_receive('make_environment').and_return( {'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'} ) flexmock(module).should_receive('make_dump_path') @@ -900,7 +901,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -919,7 +920,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ '--command', 'ANALYZE', ), - extra_environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -958,7 +959,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return( + flexmock(module).should_receive('make_environment').and_return( {'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'} ) flexmock(module).should_receive('make_dump_path') @@ -982,7 +983,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1001,7 +1002,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ '--command', 'ANALYZE', ), - extra_environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}, + environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1034,7 +1035,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1051,7 +1052,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1065,7 +1066,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1091,7 +1092,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1103,11 +1104,11 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ('psql', '--no-password', '--no-psqlrc', '--quiet', '--command', 'ANALYZE'), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1133,7 +1134,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1141,7 +1142,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1154,7 +1155,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1187,7 +1188,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1208,7 +1209,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): processes=[extract_process], output_log_level=logging.DEBUG, input_file=extract_process.stdout, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1226,7 +1227,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1251,7 +1252,7 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') flexmock(module).should_receive('execute_command_with_processes').never() @@ -1278,7 +1279,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1295,7 +1296,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): processes=[], output_log_level=logging.DEBUG, input_file=None, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1308,7 +1309,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( @@ -1333,7 +1334,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas(): flexmock(module.borgmatic.hooks.credential.parse).should_receive( 'resolve_credential' ).replace_with(lambda value, config: value) - flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) + flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') flexmock(module).should_receive('execute_command_with_processes').with_args( @@ -1354,7 +1355,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas(): processes=[], output_log_level=logging.DEBUG, input_file=None, - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() flexmock(module).should_receive('execute_command').with_args( ( @@ -1367,7 +1368,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas(): '--command', 'ANALYZE', ), - extra_environment={'PGSSLMODE': 'disable'}, + environment={'PGSSLMODE': 'disable'}, ).once() module.restore_data_source_dump( diff --git a/tests/unit/hooks/test_command.py b/tests/unit/hooks/test_command.py index 7f2e7384..5d3d285a 100644 --- a/tests/unit/hooks/test_command.py +++ b/tests/unit/hooks/test_command.py @@ -45,7 +45,7 @@ def test_make_environment_with_pyinstaller_clears_LD_LIBRARY_PATH(): def test_make_environment_with_pyinstaller_and_LD_LIBRARY_PATH_ORIG_copies_it_into_LD_LIBRARY_PATH(): assert module.make_environment( {'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib'}, sys_module=flexmock(frozen=True, _MEIPASS='yup') - ) == {'LD_LIBRARY_PATH': '/lib/lib/lib'} + ) == {'LD_LIBRARY_PATH_ORIG': '/lib/lib/lib', 'LD_LIBRARY_PATH': '/lib/lib/lib'} def test_execute_hook_invokes_each_command(): @@ -57,7 +57,7 @@ def test_execute_hook_invokes_each_command(): [':'], output_log_level=logging.WARNING, shell=True, - extra_environment={}, + environment={}, ).once() module.execute_hook([':'], None, 'config.yaml', 'pre-backup', dry_run=False) @@ -72,13 +72,13 @@ def test_execute_hook_with_multiple_commands_invokes_each_command(): [':'], output_log_level=logging.WARNING, shell=True, - extra_environment={}, + environment={}, ).once() flexmock(module.borgmatic.execute).should_receive('execute_command').with_args( ['true'], output_log_level=logging.WARNING, shell=True, - extra_environment={}, + environment={}, ).once() module.execute_hook([':', 'true'], None, 'config.yaml', 'pre-backup', dry_run=False) @@ -95,7 +95,7 @@ def test_execute_hook_with_umask_sets_that_umask(): [':'], output_log_level=logging.WARNING, shell=True, - extra_environment={}, + environment={}, ) module.execute_hook([':'], 77, 'config.yaml', 'pre-backup', dry_run=False) @@ -124,7 +124,7 @@ def test_execute_hook_on_error_logs_as_error(): [':'], output_log_level=logging.ERROR, shell=True, - extra_environment={}, + environment={}, ).once() module.execute_hook([':'], None, 'config.yaml', 'on-error', dry_run=False) diff --git a/tests/unit/test_execute.py b/tests/unit/test_execute.py index c9ca6e77..4d39fe3b 100644 --- a/tests/unit/test_execute.py +++ b/tests/unit/test_execute.py @@ -159,8 +159,15 @@ def test_mask_command_secrets_passes_through_other_commands(): ('foo', 'bar'), None, None, - {'DBPASS': 'secret', 'OTHER': 'thing'}, - 'DBPASS=*** OTHER=*** foo bar', + {'UNKNOWN': 'secret', 'OTHER': 'thing'}, + 'foo bar', + ), + ( + ('foo', 'bar'), + None, + None, + {'PGTHING': 'secret', 'BORG_OTHER': 'thing'}, + 'PGTHING=*** BORG_OTHER=*** foo bar', ), ), ) @@ -176,7 +183,6 @@ def test_log_command_logs_command_constructed_from_arguments( def test_execute_command_calls_full_command(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -199,7 +205,6 @@ def test_execute_command_calls_full_command_with_output_file(): full_command = ['foo', 'bar'] output_file = flexmock(name='test') flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -221,7 +226,6 @@ def test_execute_command_calls_full_command_with_output_file(): def test_execute_command_calls_full_command_without_capturing_output(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -245,7 +249,6 @@ def test_execute_command_calls_full_command_with_input_file(): full_command = ['foo', 'bar'] input_file = flexmock(name='test') flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=input_file, @@ -267,7 +270,6 @@ def test_execute_command_calls_full_command_with_input_file(): def test_execute_command_calls_full_command_with_shell(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( ' '.join(full_command), stdin=None, @@ -286,24 +288,23 @@ def test_execute_command_calls_full_command_with_shell(): assert output is None -def test_execute_command_calls_full_command_with_extra_environment(): +def test_execute_command_calls_full_command_with_environment(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, stdout=module.subprocess.PIPE, stderr=module.subprocess.STDOUT, shell=False, - env={'a': 'b', 'c': 'd'}, + env={'a': 'b'}, cwd=None, close_fds=True, ).and_return(flexmock(stdout=None)).once() flexmock(module.borgmatic.logger).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('log_outputs') - output = module.execute_command(full_command, extra_environment={'c': 'd'}) + output = module.execute_command(full_command, environment={'a': 'b'}) assert output is None @@ -311,7 +312,6 @@ def test_execute_command_calls_full_command_with_extra_environment(): def test_execute_command_calls_full_command_with_working_directory(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -333,21 +333,20 @@ def test_execute_command_calls_full_command_with_working_directory(): def test_execute_command_with_BORG_PASSPHRASE_FD_leaves_file_descriptors_open(): full_command = ['foo', 'bar'] flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, stdout=module.subprocess.PIPE, stderr=module.subprocess.STDOUT, shell=False, - env={'a': 'b', 'BORG_PASSPHRASE_FD': '4'}, + env={'BORG_PASSPHRASE_FD': '4'}, cwd=None, close_fds=False, ).and_return(flexmock(stdout=None)).once() flexmock(module.borgmatic.logger).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('log_outputs') - output = module.execute_command(full_command, extra_environment={'BORG_PASSPHRASE_FD': '4'}) + output = module.execute_command(full_command, environment={'BORG_PASSPHRASE_FD': '4'}) assert output is None @@ -356,7 +355,6 @@ def test_execute_command_without_run_to_completion_returns_process(): full_command = ['foo', 'bar'] process = flexmock() flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -377,7 +375,6 @@ def test_execute_command_and_capture_output_returns_stdout(): full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, @@ -396,7 +393,6 @@ def test_execute_command_and_capture_output_with_capture_stderr_returns_stderr() full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=module.subprocess.STDOUT, @@ -416,7 +412,6 @@ def test_execute_command_and_capture_output_returns_output_when_process_error_is expected_output = '[]' err_output = b'[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, @@ -438,7 +433,6 @@ def test_execute_command_and_capture_output_raises_when_command_errors(): full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, @@ -459,7 +453,6 @@ def test_execute_command_and_capture_output_returns_output_with_shell(): full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( 'foo bar', stderr=None, @@ -474,22 +467,21 @@ def test_execute_command_and_capture_output_returns_output_with_shell(): assert output == expected_output -def test_execute_command_and_capture_output_returns_output_with_extra_environment(): +def test_execute_command_and_capture_output_returns_output_with_environment(): full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, shell=False, - env={'a': 'b', 'c': 'd'}, + env={'a': 'b'}, cwd=None, close_fds=True, ).and_return(flexmock(decode=lambda: expected_output)).once() output = module.execute_command_and_capture_output( - full_command, shell=False, extra_environment={'c': 'd'} + full_command, shell=False, environment={'a': 'b'} ) assert output == expected_output @@ -499,7 +491,6 @@ def test_execute_command_and_capture_output_returns_output_with_working_director full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, @@ -520,12 +511,11 @@ def test_execute_command_and_capture_output_with_BORG_PASSPHRASE_FD_leaves_file_ full_command = ['foo', 'bar'] expected_output = '[]' flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('check_output').with_args( full_command, stderr=None, shell=False, - env={'a': 'b', 'BORG_PASSPHRASE_FD': '4'}, + env={'BORG_PASSPHRASE_FD': '4'}, cwd=None, close_fds=False, ).and_return(flexmock(decode=lambda: expected_output)).once() @@ -533,7 +523,7 @@ def test_execute_command_and_capture_output_with_BORG_PASSPHRASE_FD_leaves_file_ output = module.execute_command_and_capture_output( full_command, shell=False, - extra_environment={'BORG_PASSPHRASE_FD': '4'}, + environment={'BORG_PASSPHRASE_FD': '4'}, ) assert output == expected_output @@ -543,7 +533,6 @@ def test_execute_command_with_processes_calls_full_command(): full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -566,7 +555,6 @@ def test_execute_command_with_processes_returns_output_with_output_log_level_non full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) process = flexmock(stdout=None) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, @@ -591,7 +579,6 @@ def test_execute_command_with_processes_calls_full_command_with_output_file(): processes = (flexmock(),) output_file = flexmock(name='test') flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -614,7 +601,6 @@ def test_execute_command_with_processes_calls_full_command_without_capturing_out full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -641,7 +627,6 @@ def test_execute_command_with_processes_calls_full_command_with_input_file(): processes = (flexmock(),) input_file = flexmock(name='test') flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=input_file, @@ -664,7 +649,6 @@ def test_execute_command_with_processes_calls_full_command_with_shell(): full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( ' '.join(full_command), stdin=None, @@ -683,27 +667,24 @@ def test_execute_command_with_processes_calls_full_command_with_shell(): assert output is None -def test_execute_command_with_processes_calls_full_command_with_extra_environment(): +def test_execute_command_with_processes_calls_full_command_with_environment(): full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, stdout=module.subprocess.PIPE, stderr=module.subprocess.STDOUT, shell=False, - env={'a': 'b', 'c': 'd'}, + env={'a': 'b'}, cwd=None, close_fds=True, ).and_return(flexmock(stdout=None)).once() flexmock(module.borgmatic.logger).should_receive('Log_prefix').and_return(flexmock()) flexmock(module).should_receive('log_outputs') - output = module.execute_command_with_processes( - full_command, processes, extra_environment={'c': 'd'} - ) + output = module.execute_command_with_processes(full_command, processes, environment={'a': 'b'}) assert output is None @@ -712,7 +693,6 @@ def test_execute_command_with_processes_calls_full_command_with_working_director full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, @@ -737,14 +717,13 @@ def test_execute_command_with_processes_with_BORG_PASSPHRASE_FD_leaves_file_desc full_command = ['foo', 'bar'] processes = (flexmock(),) flexmock(module).should_receive('log_command') - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None, stdout=module.subprocess.PIPE, stderr=module.subprocess.STDOUT, shell=False, - env={'a': 'b', 'BORG_PASSPHRASE_FD': '4'}, + env={'BORG_PASSPHRASE_FD': '4'}, cwd=None, close_fds=False, ).and_return(flexmock(stdout=None)).once() @@ -754,7 +733,7 @@ def test_execute_command_with_processes_with_BORG_PASSPHRASE_FD_leaves_file_desc output = module.execute_command_with_processes( full_command, processes, - extra_environment={'BORG_PASSPHRASE_FD': '4'}, + environment={'BORG_PASSPHRASE_FD': '4'}, ) assert output is None @@ -767,7 +746,6 @@ def test_execute_command_with_processes_kills_processes_on_error(): process.should_receive('poll') process.should_receive('kill').once() processes = (process,) - flexmock(module.os, environ={'a': 'b'}) flexmock(module.subprocess).should_receive('Popen').with_args( full_command, stdin=None,