From 28fef3264bff9a15e07d4a39ce11ca44ddf148e8 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Mon, 7 Mar 2022 15:32:07 -0800 Subject: [PATCH] Fix handling of "patterns_from" and "exclude_from" options to error instead of warning when referencing unreadable files and running "create" action (#486). --- NEWS | 2 ++ borgmatic/borg/create.py | 14 ++++++++ tests/unit/borg/test_create.py | 60 ++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/NEWS b/NEWS index ad48a0a..6b471c5 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ 1.5.24.dev0 * Add "working_directory" option to support source directories with relative paths (#431). + * #486: Fix handling of "patterns_from" and "exclude_from" options to error instead of warning when + referencing unreadable files and running "create" action. 1.5.23 * #394: Compact repository segments and free space with new "borgmatic compact" action. Borg 1.2+ diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 4863ec4..0be170d 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -113,6 +113,18 @@ def write_pattern_file(patterns=None): return pattern_file +def ensure_files_readable(*filename_lists): + ''' + Given a sequence of filename sequences, ensure that each filename is openable. This prevents + unreadable files from being passed to Borg, which in certain situations only warns instead of + erroring. + ''' + for file_object in itertools.chain.from_iterable( + filename_list for filename_list in filename_lists if filename_list + ): + open(file_object).close() + + def make_pattern_flags(location_config, pattern_filename=None): ''' Given a location config dict with a potential patterns_from option, and a filename containing @@ -255,6 +267,8 @@ def create_archive( ('--remote-ratelimit', str(remote_rate_limit)) if remote_rate_limit else () ) + ensure_files_readable(location_config.get('patterns_from'), location_config.get('exclude_from')) + full_command = ( tuple(local_path.split(' ')) + ('create',) diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 832524a..e89aa15 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -1,4 +1,5 @@ import logging +import sys import pytest from flexmock import flexmock @@ -119,6 +120,23 @@ def test_write_pattern_file_with_empty_exclude_patterns_does_not_raise(): module.write_pattern_file([]) +@pytest.mark.parametrize( + 'filename_lists,opened_filenames', + ( + ([('foo', 'bar'), ('baz', 'quux')], ('foo', 'bar', 'baz', 'quux')), + ([None, ('foo', 'bar')], ('foo', 'bar')), + ([None, None], ()), + ), +) +def test_ensure_files_readable_opens_filenames(filename_lists, opened_filenames): + for expected_filename in opened_filenames: + flexmock(sys.modules['builtins']).should_receive('open').with_args( + expected_filename + ).and_return(flexmock(close=lambda: None)) + + module.ensure_files_readable(*filename_lists) + + def test_make_pattern_flags_includes_pattern_filename_when_given(): pattern_flags = module.make_pattern_flags( location_config={'patterns': ['R /', '- /var']}, pattern_filename='/tmp/patterns' @@ -269,6 +287,7 @@ def test_create_archive_calls_borg_with_parameters(): 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).should_receive('execute_command').with_args( @@ -304,6 +323,7 @@ def test_create_archive_with_patterns_calls_borg_with_patterns(): flexmock(name='/tmp/patterns') ).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(pattern_flags) flexmock(module).should_receive('make_exclude_flags').and_return(()) flexmock(module).should_receive('execute_command').with_args( @@ -339,6 +359,7 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes(): flexmock(name='/tmp/excludes') ) 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(exclude_flags) flexmock(module).should_receive('execute_command').with_args( @@ -371,6 +392,7 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter(): 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).should_receive('execute_command').with_args( @@ -404,6 +426,7 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output(): 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).should_receive('execute_command').with_args( @@ -438,6 +461,7 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter(): 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).should_receive('execute_command').with_args( @@ -471,6 +495,7 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output(): 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).should_receive('execute_command').with_args( @@ -505,6 +530,7 @@ def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter(): 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).should_receive('execute_command').with_args( @@ -539,6 +565,7 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats_paramete 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).should_receive('execute_command').with_args( @@ -573,6 +600,7 @@ def test_create_archive_with_checkpoint_interval_calls_borg_with_checkpoint_inte 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).should_receive('execute_command').with_args( @@ -605,6 +633,7 @@ def test_create_archive_with_chunker_params_calls_borg_with_chunker_params_param 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).should_receive('execute_command').with_args( @@ -637,6 +666,7 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters( 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).should_receive('execute_command').with_args( @@ -674,6 +704,7 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_ 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(feature_available) + 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).should_receive('execute_command').with_args( @@ -708,6 +739,7 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory 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).should_receive('execute_command').with_args( @@ -741,6 +773,7 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par 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).should_receive('execute_command').with_args( @@ -779,6 +812,7 @@ def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter 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(feature_available) + 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).should_receive('execute_command').with_args( @@ -812,6 +846,7 @@ def test_create_archive_with_read_special_calls_borg_with_read_special_parameter 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).should_receive('execute_command').with_args( @@ -852,6 +887,7 @@ def test_create_archive_with_basic_option_calls_borg_with_corresponding_paramete 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).should_receive('execute_command').with_args( @@ -896,6 +932,7 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete 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(feature_available) + 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).should_receive('execute_command').with_args( @@ -940,6 +977,7 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para 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(feature_available) + 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).should_receive('execute_command').with_args( @@ -973,6 +1011,7 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters( 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).should_receive('execute_command').with_args( @@ -1006,6 +1045,7 @@ def test_create_archive_with_local_path_calls_borg_via_local_path(): 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).should_receive('execute_command').with_args( @@ -1039,6 +1079,7 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters( 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).should_receive('execute_command').with_args( @@ -1072,6 +1113,7 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters(): 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).should_receive('execute_command').with_args( @@ -1104,6 +1146,7 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters(): 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).should_receive('execute_command').with_args( @@ -1136,6 +1179,7 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_warning_o 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).should_receive('execute_command').with_args( @@ -1169,6 +1213,7 @@ def test_create_archive_with_stats_and_log_info_calls_borg_with_stats_parameter_ 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).should_receive('execute_command').with_args( @@ -1203,6 +1248,7 @@ def test_create_archive_with_files_calls_borg_with_list_parameter_and_warning_ou 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).should_receive('execute_command').with_args( @@ -1236,6 +1282,7 @@ def test_create_archive_with_files_and_log_info_calls_borg_with_list_parameter_a 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).should_receive('execute_command').with_args( @@ -1270,6 +1317,7 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para 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).should_receive('execute_command').with_args( @@ -1304,6 +1352,7 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter(): 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).should_receive('execute_command').with_args( @@ -1338,6 +1387,7 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr 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).should_receive('execute_command_with_processes').with_args( @@ -1374,6 +1424,7 @@ def test_create_archive_with_json_calls_borg_with_json_parameter(): 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).should_receive('execute_command').with_args( @@ -1409,6 +1460,7 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_parameter() 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).should_receive('execute_command').with_args( @@ -1445,6 +1497,7 @@ def test_create_archive_with_source_directories_glob_expands(): 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).should_receive('execute_command').with_args( @@ -1478,6 +1531,7 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through 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).should_receive('execute_command').with_args( @@ -1511,6 +1565,7 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories(): 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).should_receive('execute_command').with_args( @@ -1543,6 +1598,7 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name(): 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).should_receive('execute_command').with_args( @@ -1575,6 +1631,7 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders(): 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).should_receive('execute_command').with_args( @@ -1607,6 +1664,7 @@ def test_create_archive_with_repository_accepts_borg_placeholders(): 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).should_receive('execute_command').with_args( @@ -1639,6 +1697,7 @@ def test_create_archive_with_extra_borg_options_calls_borg_with_extra_options(): 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).should_receive('execute_command').with_args( @@ -1672,6 +1731,7 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes(): 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).should_receive('execute_command_with_processes').with_args(