From 2898e63166aecbdcfa8b26a092fbaabda7e4cd6a Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Fri, 12 Aug 2022 23:54:13 -0700 Subject: [PATCH] Update create action for Borg 2 support (#557). --- NEWS | 3 +- borgmatic/borg/create.py | 6 +- tests/unit/borg/test_create.py | 243 +++++++++++++++++++++++++++------ 3 files changed, 210 insertions(+), 42 deletions(-) diff --git a/NEWS b/NEWS index 5615aead5..0ad278770 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ 2.0.0.dev0 - * #557: Support for Borg 2 while still working with Borg 1. + * #557: Support for Borg 2 while still working with Borg 1. If you install Borg 2, you'll need to + manually "borg transfer" or "borgmatic transfer" any existing Borg 1 repositories before use. * #565: Fix handling of "repository" and "data" consistency checks to prevent invalid Borg flags. * #566: Modify "mount" and "extract" actions to require the "--repository" flag when multiple repositories are configured. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 1a7ae4004..c5a81c535 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -299,9 +299,9 @@ def create_archive( + (('--json',) if json else ()) + (tuple(extra_borg_options.split(' ')) if extra_borg_options else ()) + ( - '{repository}::{archive_name_format}'.format( - repository=repository, archive_name_format=archive_name_format - ), + ('--repo', repository, archive_name_format) + if feature.available(feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, local_borg_version) + else (f'{repository}::{archive_name_format}',) ) + sources ) diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index c51bd34fa..5b055461f 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -277,7 +277,7 @@ def test_borgmatic_source_directories_defaults_when_directory_not_given(): DEFAULT_ARCHIVE_NAME = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}' -ARCHIVE_WITH_PATHS = ('repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'bar') +REPO_ARCHIVE_WITH_PATHS = (f'repo::{DEFAULT_ARCHIVE_NAME}', 'foo', 'bar') def test_create_archive_calls_borg_with_parameters(): @@ -292,9 +292,50 @@ def test_create_archive_calls_borg_with_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ARCHIVE_WITH_PATHS, + ('borg', 'create') + REPO_ARCHIVE_WITH_PATHS, + output_log_level=logging.INFO, + output_file=None, + borg_local_path='borg', + working_directory=None, + extra_environment=None, + ) + + module.create_archive( + dry_run=False, + repository='repo', + location_config={ + 'source_directories': ['foo', 'bar'], + 'repositories': ['repo'], + 'exclude_patterns': None, + }, + storage_config={}, + local_borg_version='1.2.3', + ) + + +def test_create_archive_with_borg_features_calls_borg_with_repo_flag(): + flexmock(module).should_receive('borgmatic_source_directories').and_return([]) + flexmock(module).should_receive('deduplicate_directories').and_return(('foo', 'bar')) + flexmock(module).should_receive('map_directories_to_devices').and_return({}) + flexmock(module).should_receive('expand_directories').and_return(()) + flexmock(module.os.path).should_receive('expanduser').and_raise(TypeError) + flexmock(module).should_receive('expand_home_directories').and_return(()) + flexmock(module).should_receive('write_pattern_file').and_return(None) + flexmock(module.feature).should_receive('available').and_return(True) + flexmock(module).should_receive('ensure_files_readable') + flexmock(module).should_receive('make_pattern_flags').and_return(()) + flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(True) + flexmock(module.environment).should_receive('make_environment') + flexmock(module).should_receive('execute_command').with_args( + ('borg', 'create', '--repo', 'repo', DEFAULT_ARCHIVE_NAME, 'foo', 'bar'), output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -327,10 +368,13 @@ def test_create_archive_calls_borg_with_environment(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) environment = {'BORG_THINGY': 'YUP'} flexmock(module.environment).should_receive('make_environment').and_return(environment) flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ARCHIVE_WITH_PATHS, + ('borg', 'create') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -366,9 +410,12 @@ def test_create_archive_with_patterns_calls_borg_with_patterns(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(pattern_flags) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + pattern_flags + ARCHIVE_WITH_PATHS, + ('borg', 'create') + pattern_flags + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -404,9 +451,12 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(exclude_flags) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + exclude_flags + ARCHIVE_WITH_PATHS, + ('borg', 'create') + exclude_flags + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -439,9 +489,12 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--info') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -475,9 +528,12 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--json') + REPO_ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', @@ -512,9 +568,12 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--debug', '--show-rc') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--debug', '--show-rc') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -548,9 +607,12 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--json') + REPO_ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', @@ -585,9 +647,12 @@ def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--dry-run') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--dry-run') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -622,9 +687,12 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info', '--dry-run') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--info', '--dry-run') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -659,9 +727,12 @@ def test_create_archive_with_checkpoint_interval_calls_borg_with_checkpoint_inte flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--checkpoint-interval', '600') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--checkpoint-interval', '600') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -694,9 +765,12 @@ def test_create_archive_with_chunker_params_calls_borg_with_chunker_params_param flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--chunker-params', '1,2,3,4') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--chunker-params', '1,2,3,4') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -729,9 +803,12 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--compression', 'rle') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--compression', 'rle') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -769,9 +846,12 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_ flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', option_flag, '100') + ARCHIVE_WITH_PATHS, + ('borg', 'create', option_flag, '100') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -806,9 +886,12 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ARCHIVE_WITH_PATHS, + ('borg', 'create') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -842,9 +925,12 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--one-file-system') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--one-file-system') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -883,9 +969,12 @@ def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', option_flag) + ARCHIVE_WITH_PATHS, + ('borg', 'create', option_flag) + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -919,9 +1008,12 @@ def test_create_archive_with_read_special_calls_borg_with_read_special_parameter flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--read-special') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--read-special') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -962,9 +1054,12 @@ def test_create_archive_with_basic_option_calls_borg_with_corresponding_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, + ('borg', 'create') + ((option_flag,) if option_flag else ()) + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1009,9 +1104,12 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, + ('borg', 'create') + ((option_flag,) if option_flag else ()) + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1056,9 +1154,12 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS, + ('borg', 'create') + ((option_flag,) if option_flag else ()) + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1092,9 +1193,12 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--files-cache', 'ctime,size') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--files-cache', 'ctime,size') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1128,9 +1232,12 @@ def test_create_archive_with_local_path_calls_borg_via_local_path(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg1', 'create') + ARCHIVE_WITH_PATHS, + ('borg1', 'create') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg1', @@ -1164,9 +1271,12 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters( flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--remote-path', 'borg1') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--remote-path', 'borg1') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1200,9 +1310,12 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--umask', '740') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--umask', '740') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1235,9 +1348,12 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--lock-wait', '5') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--lock-wait', '5') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1270,9 +1386,12 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_warning_o flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--stats') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--stats') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.WARNING, output_file=None, borg_local_path='borg', @@ -1306,9 +1425,12 @@ def test_create_archive_with_stats_and_log_info_calls_borg_with_stats_parameter_ flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info', '--stats') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--info', '--stats') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1343,9 +1465,12 @@ def test_create_archive_with_files_calls_borg_with_list_parameter_and_warning_ou flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--list', '--filter', 'AME-') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--list', '--filter', 'AME-') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.WARNING, output_file=None, borg_local_path='borg', @@ -1379,9 +1504,12 @@ def test_create_archive_with_files_and_log_info_calls_borg_with_list_parameter_a flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--list', '--filter', 'AME-', '--info') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--list', '--filter', 'AME-', '--info') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1416,9 +1544,12 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--info', '--progress') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--info', '--progress') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', @@ -1453,9 +1584,12 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--progress') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--progress') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, borg_local_path='borg', @@ -1490,10 +1624,13 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command_with_processes').with_args( ('borg', 'create', '--one-file-system', '--read-special', '--progress') - + ARCHIVE_WITH_PATHS, + + REPO_ARCHIVE_WITH_PATHS, processes=processes, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, @@ -1529,9 +1666,12 @@ def test_create_archive_with_json_calls_borg_with_json_parameter(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--json') + REPO_ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', @@ -1567,9 +1707,12 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_parameter() flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--json') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--json') + REPO_ARCHIVE_WITH_PATHS, output_log_level=None, output_file=None, borg_local_path='borg', @@ -1606,6 +1749,9 @@ def test_create_archive_with_source_directories_glob_expands(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'), @@ -1642,6 +1788,9 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo*'), @@ -1678,6 +1827,9 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'), @@ -1713,6 +1865,9 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::ARCHIVE_NAME', 'foo', 'bar'), @@ -1748,6 +1903,9 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', 'repo::Documents_{hostname}-{now}', 'foo', 'bar'), @@ -1783,6 +1941,9 @@ def test_create_archive_with_repository_accepts_borg_placeholders(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( ('borg', 'create', '{fqdn}::Documents_{hostname}-{now}', 'foo', 'bar'), @@ -1818,9 +1979,12 @@ def test_create_archive_with_extra_borg_options_calls_borg_with_extra_options(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command').with_args( - ('borg', 'create', '--extra', '--options') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--extra', '--options') + REPO_ARCHIVE_WITH_PATHS, output_log_level=logging.INFO, output_file=None, borg_local_path='borg', @@ -1854,9 +2018,12 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes(): flexmock(module).should_receive('ensure_files_readable') flexmock(module).should_receive('make_pattern_flags').and_return(()) flexmock(module).should_receive('make_exclude_flags').and_return(()) + flexmock(module.feature).should_receive('available').with_args( + module.feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, '1.2.3' + ).and_return(False) flexmock(module.environment).should_receive('make_environment') flexmock(module).should_receive('execute_command_with_processes').with_args( - ('borg', 'create', '--one-file-system', '--read-special') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--one-file-system', '--read-special') + REPO_ARCHIVE_WITH_PATHS, processes=processes, output_log_level=logging.INFO, output_file=None,