Add support for Borg 2's "--match-archives" flag (replaces "--glob-archives") (#591).

This commit is contained in:
Dan Helfman 2022-10-03 22:50:37 -07:00
parent ae036aebd7
commit 2774c2e4c0
20 changed files with 251 additions and 190 deletions

2
NEWS
View File

@ -3,6 +3,8 @@
files for a "create" action to prevent Borg from hanging. files for a "create" action to prevent Borg from hanging.
* #587: Warn when ignoring a configured "read_special" value of false, as true is needed when * #587: Warn when ignoring a configured "read_special" value of false, as true is needed when
database hooks are enabled. database hooks are enabled.
* #591: Add support for Borg 2's "--match-archives" flag (replaces "--glob-archives").
* Fix for "borgmatic --archive latest" not finding the latest archive when a verbosity is set.
1.7.2 1.7.2
* #577: Fix regression in which "borgmatic info --archive ..." showed repository info instead of * #577: Fix regression in which "borgmatic info --archive ..." showed repository info instead of

View File

@ -5,7 +5,7 @@ import logging
import os import os
import pathlib import pathlib
from borgmatic.borg import environment, extract, flags, rinfo, state from borgmatic.borg import environment, extract, feature, flags, rinfo, state
from borgmatic.execute import DO_NOT_CAPTURE, execute_command from borgmatic.execute import DO_NOT_CAPTURE, execute_command
DEFAULT_CHECKS = ( DEFAULT_CHECKS = (
@ -146,9 +146,10 @@ def filter_checks_on_frequency(
return tuple(filtered_checks) return tuple(filtered_checks)
def make_check_flags(checks, check_last=None, prefix=None): def make_check_flags(local_borg_version, checks, check_last=None, prefix=None):
''' '''
Given a parsed sequence of checks, transform it into tuple of command-line flags. Given the local Borg version and a parsed sequence of checks, transform the checks into tuple of
command-line flags.
For example, given parsed checks of: For example, given parsed checks of:
@ -163,14 +164,17 @@ def make_check_flags(checks, check_last=None, prefix=None):
Additionally, if a check_last value is given and "archives" is in checks, then include a Additionally, if a check_last value is given and "archives" is in checks, then include a
"--last" flag. And if a prefix value is given and "archives" is in checks, then include a "--last" flag. And if a prefix value is given and "archives" is in checks, then include a
"--glob-archives" flag. "--match-archives" flag.
''' '''
if 'archives' in checks: if 'archives' in checks:
last_flags = ('--last', str(check_last)) if check_last else () last_flags = ('--last', str(check_last)) if check_last else ()
glob_archives_flags = ('--glob-archives', f'{prefix}*') if prefix else () if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version):
match_archives_flags = ('--match-archives', f'sh:{prefix}*') if prefix else ()
else:
match_archives_flags = ('--glob-archives', f'{prefix}*') if prefix else ()
else: else:
last_flags = () last_flags = ()
glob_archives_flags = () match_archives_flags = ()
if check_last: if check_last:
logger.info('Ignoring check_last option, as "archives" is not in consistency checks') logger.info('Ignoring check_last option, as "archives" is not in consistency checks')
if prefix: if prefix:
@ -184,7 +188,7 @@ def make_check_flags(checks, check_last=None, prefix=None):
else: else:
data_flags = () data_flags = ()
common_flags = last_flags + glob_archives_flags + data_flags common_flags = last_flags + match_archives_flags + data_flags
if {'repository', 'archives'}.issubset(set(checks)): if {'repository', 'archives'}.issubset(set(checks)):
return common_flags return common_flags
@ -298,7 +302,7 @@ def check_archives(
full_command = ( full_command = (
(local_path, 'check') (local_path, 'check')
+ (('--repair',) if repair else ()) + (('--repair',) if repair else ())
+ make_check_flags(checks, check_last, prefix) + make_check_flags(local_borg_version, checks, check_last, prefix)
+ (('--remote-path', remote_path) if remote_path else ()) + (('--remote-path', remote_path) if remote_path else ())
+ (('--lock-wait', str(lock_wait)) if lock_wait else ()) + (('--lock-wait', str(lock_wait)) if lock_wait else ())
+ verbosity_flags + verbosity_flags

View File

@ -13,6 +13,7 @@ class Feature(Enum):
RCREATE = 7 RCREATE = 7
RLIST = 8 RLIST = 8
RINFO = 9 RINFO = 9
MATCH_ARCHIVES = 10
FEATURE_TO_MINIMUM_BORG_VERSION = { FEATURE_TO_MINIMUM_BORG_VERSION = {
@ -25,6 +26,7 @@ FEATURE_TO_MINIMUM_BORG_VERSION = {
Feature.RCREATE: parse_version('2.0.0a2'), # borg rcreate Feature.RCREATE: parse_version('2.0.0a2'), # borg rcreate
Feature.RLIST: parse_version('2.0.0a2'), # borg rlist Feature.RLIST: parse_version('2.0.0a2'), # borg rlist
Feature.RINFO: parse_version('2.0.0a2'), # borg rinfo Feature.RINFO: parse_version('2.0.0a2'), # borg rinfo
Feature.MATCH_ARCHIVES: parse_version('2.0.0b3'), # borg --match-archives
} }

View File

@ -1,6 +1,6 @@
import logging import logging
from borgmatic.borg import environment, flags from borgmatic.borg import environment, feature, flags
from borgmatic.execute import execute_command from borgmatic.execute import execute_command
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -36,7 +36,11 @@ def display_archives_info(
+ flags.make_flags('remote-path', remote_path) + flags.make_flags('remote-path', remote_path)
+ flags.make_flags('lock-wait', lock_wait) + flags.make_flags('lock-wait', lock_wait)
+ ( + (
flags.make_flags('glob-archives', f'{info_arguments.prefix}*') (
flags.make_flags('match-archives', f'sh:{info_arguments.prefix}*')
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else flags.make_flags('glob-archives', f'{info_arguments.prefix}*')
)
if info_arguments.prefix if info_arguments.prefix
else () else ()
) )
@ -44,7 +48,11 @@ def display_archives_info(
info_arguments, excludes=('repository', 'archive', 'prefix') info_arguments, excludes=('repository', 'archive', 'prefix')
) )
+ flags.make_repository_flags(repository, local_borg_version) + flags.make_repository_flags(repository, local_borg_version)
+ flags.make_flags('glob-archives', info_arguments.archive) + (
flags.make_flags('match-archives', info_arguments.archive)
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else flags.make_flags('glob-archives', info_arguments.archive)
)
) )
return execute_command( return execute_command(

View File

@ -9,7 +9,7 @@ from borgmatic.execute import execute_command
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST = ('prefix', 'glob_archives', 'sort_by', 'first', 'last') ARCHIVE_FILTER_FLAGS_MOVED_TO_RLIST = ('prefix', 'match_archives', 'sort_by', 'first', 'last')
MAKE_FLAGS_EXCLUDES = ( MAKE_FLAGS_EXCLUDES = (
'repository', 'repository',
'archive', 'archive',
@ -111,7 +111,7 @@ def list_archive(
format=list_arguments.format, format=list_arguments.format,
json=list_arguments.json, json=list_arguments.json,
prefix=list_arguments.prefix, prefix=list_arguments.prefix,
glob_archives=list_arguments.glob_archives, match_archives=list_arguments.match_archives,
sort_by=list_arguments.sort_by, sort_by=list_arguments.sort_by,
first=list_arguments.first, first=list_arguments.first,
last=list_arguments.last, last=list_arguments.last,
@ -143,7 +143,7 @@ def list_archive(
format=None, format=None,
json=None, json=None,
prefix=list_arguments.prefix, prefix=list_arguments.prefix,
glob_archives=list_arguments.glob_archives, match_archives=list_arguments.match_archives,
sort_by=list_arguments.sort_by, sort_by=list_arguments.sort_by,
first=list_arguments.first, first=list_arguments.first,
last=list_arguments.last, last=list_arguments.last,

View File

@ -39,7 +39,11 @@ def mount_archive(
+ ( + (
( (
flags.make_repository_flags(repository, local_borg_version) flags.make_repository_flags(repository, local_borg_version)
+ ('--glob-archives', archive) + (
('--match-archives', archive)
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else ('--glob-archives', archive)
)
) )
if feature.available(feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, local_borg_version) if feature.available(feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, local_borg_version)
else ( else (

View File

@ -1,12 +1,12 @@
import logging import logging
from borgmatic.borg import environment, flags from borgmatic.borg import environment, feature, flags
from borgmatic.execute import execute_command from borgmatic.execute import execute_command
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def make_prune_flags(retention_config): def make_prune_flags(retention_config, local_borg_version):
''' '''
Given a retention config dict mapping from option name to value, tranform it into an iterable of Given a retention config dict mapping from option name to value, tranform it into an iterable of
command-line name-value flag pairs. command-line name-value flag pairs.
@ -24,8 +24,12 @@ def make_prune_flags(retention_config):
''' '''
config = retention_config.copy() config = retention_config.copy()
prefix = config.pop('prefix', '{hostname}-') prefix = config.pop('prefix', '{hostname}-')
if prefix: if prefix:
config['glob_archives'] = f'{prefix}*' if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version):
config['match_archives'] = f'sh:{prefix}*'
else:
config['glob_archives'] = f'{prefix}*'
return ( return (
('--' + option_name.replace('_', '-'), str(value)) for option_name, value in config.items() ('--' + option_name.replace('_', '-'), str(value)) for option_name, value in config.items()
@ -54,7 +58,11 @@ def prune_archives(
full_command = ( full_command = (
(local_path, 'prune') (local_path, 'prune')
+ tuple(element for pair in make_prune_flags(retention_config) for element in pair) + tuple(
element
for pair in make_prune_flags(retention_config, local_borg_version)
for element in pair
)
+ (('--remote-path', remote_path) if remote_path else ()) + (('--remote-path', remote_path) if remote_path else ())
+ (('--umask', str(umask)) if umask else ()) + (('--umask', str(umask)) if umask else ())
+ (('--lock-wait', str(lock_wait)) if lock_wait else ()) + (('--lock-wait', str(lock_wait)) if lock_wait else ())

View File

@ -26,8 +26,6 @@ def resolve_archive_name(
local_path, local_path,
'rlist' if feature.available(feature.Feature.RLIST, local_borg_version) else 'list', 'rlist' if feature.available(feature.Feature.RLIST, local_borg_version) else 'list',
) )
+ (('--info',) if logger.getEffectiveLevel() == logging.INFO else ())
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
+ flags.make_flags('remote-path', remote_path) + flags.make_flags('remote-path', remote_path)
+ flags.make_flags('lock-wait', lock_wait) + flags.make_flags('lock-wait', lock_wait)
+ flags.make_flags('last', 1) + flags.make_flags('last', 1)
@ -87,7 +85,11 @@ def make_rlist_command(
+ flags.make_flags('remote-path', remote_path) + flags.make_flags('remote-path', remote_path)
+ flags.make_flags('lock-wait', lock_wait) + flags.make_flags('lock-wait', lock_wait)
+ ( + (
flags.make_flags('glob-archives', f'{rlist_arguments.prefix}*') (
flags.make_flags('match-archives', f'sh:{rlist_arguments.prefix}*')
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
else flags.make_flags('glob-archives', f'{rlist_arguments.prefix}*')
)
if rlist_arguments.prefix if rlist_arguments.prefix
else () else ()
) )

View File

@ -25,12 +25,14 @@ def transfer_archives(
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ()) + (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
+ flags.make_flags('remote-path', remote_path) + flags.make_flags('remote-path', remote_path)
+ flags.make_flags('lock-wait', storage_config.get('lock_wait', None)) + flags.make_flags('lock-wait', storage_config.get('lock_wait', None))
+ flags.make_flags( + (
'glob-archives', transfer_arguments.glob_archives or transfer_arguments.archive flags.make_flags(
'match-archives', transfer_arguments.match_archives or transfer_arguments.archive
)
) )
+ flags.make_flags_from_arguments( + flags.make_flags_from_arguments(
transfer_arguments, transfer_arguments,
excludes=('repository', 'source_repository', 'archive', 'glob_archives'), excludes=('repository', 'source_repository', 'archive', 'match_archives'),
) )
+ flags.make_repository_flags(repository, local_borg_version) + flags.make_repository_flags(repository, local_borg_version)
+ flags.make_flags('other-repo', transfer_arguments.source_repository) + flags.make_flags('other-repo', transfer_arguments.source_repository)

View File

@ -293,9 +293,10 @@ def make_parsers():
) )
transfer_group.add_argument( transfer_group.add_argument(
'-a', '-a',
'--match-archives',
'--glob-archives', '--glob-archives',
metavar='GLOB', metavar='PATTERN',
help='Only transfer archives with names matching this glob', help='Only transfer archives with names matching this pattern',
) )
transfer_group.add_argument( transfer_group.add_argument(
'--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys'
@ -627,7 +628,11 @@ def make_parsers():
'-P', '--prefix', help='Only list archive names starting with this prefix' '-P', '--prefix', help='Only list archive names starting with this prefix'
) )
rlist_group.add_argument( rlist_group.add_argument(
'-a', '--glob-archives', metavar='GLOB', help='Only list archive names matching this glob' '-a',
'--match-archives',
'--glob-archives',
metavar='PATTERN',
help='Only list archive names matching this pattern',
) )
rlist_group.add_argument( rlist_group.add_argument(
'--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys'
@ -678,7 +683,11 @@ def make_parsers():
'-P', '--prefix', help='Only list archive names starting with this prefix' '-P', '--prefix', help='Only list archive names starting with this prefix'
) )
list_group.add_argument( list_group.add_argument(
'-a', '--glob-archives', metavar='GLOB', help='Only list archive names matching this glob' '-a',
'--match-archives',
'--glob-archives',
metavar='PATTERN',
help='Only list archive names matching this pattern',
) )
list_group.add_argument( list_group.add_argument(
'--successful', '--successful',
@ -747,9 +756,10 @@ def make_parsers():
) )
info_group.add_argument( info_group.add_argument(
'-a', '-a',
'--match-archives',
'--glob-archives', '--glob-archives',
metavar='GLOB', metavar='PATTERN',
help='Only show info for archive names matching this glob', help='Only show info for archive names matching this pattern',
) )
info_group.add_argument( info_group.add_argument(
'--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys' '--sort-by', metavar='KEYS', help='Comma-separated list of sorting keys'
@ -816,7 +826,7 @@ def parse_arguments(*unparsed_arguments):
if ( if (
'transfer' in arguments 'transfer' in arguments
and arguments['transfer'].archive and arguments['transfer'].archive
and arguments['transfer'].glob_archives and arguments['transfer'].match_archives
): ):
raise ValueError( raise ValueError(
'With the transfer action, only one of --archive and --glob-archives flags can be used.' 'With the transfer action, only one of --archive and --glob-archives flags can be used.'
@ -824,11 +834,11 @@ def parse_arguments(*unparsed_arguments):
if 'info' in arguments and ( if 'info' in arguments and (
(arguments['info'].archive and arguments['info'].prefix) (arguments['info'].archive and arguments['info'].prefix)
or (arguments['info'].archive and arguments['info'].glob_archives) or (arguments['info'].archive and arguments['info'].match_archives)
or (arguments['info'].prefix and arguments['info'].glob_archives) or (arguments['info'].prefix and arguments['info'].match_archives)
): ):
raise ValueError( raise ValueError(
'With the info action, only one of --archive, --prefix, or --glob-archives flags can be used.' 'With the info action, only one of --archive, --prefix, or --match-archives flags can be used.'
) )
return arguments return arguments

View File

@ -84,7 +84,7 @@ be a [Borg
pattern](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-patterns). pattern](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-patterns).
To limit the archives searched, use the standard `list` parameters for To limit the archives searched, use the standard `list` parameters for
filtering archives such as `--last`, `--archive`, `--glob-archives`, etc. For filtering archives such as `--last`, `--archive`, `--match-archives`, etc. For
example, to search only the last five archives: example, to search only the last five archives:
```bash ```bash

View File

@ -53,6 +53,7 @@ for sub_command in prune create check list info; do
| grep -v '^--first' \ | grep -v '^--first' \
| grep -v '^--format' \ | grep -v '^--format' \
| grep -v '^--glob-archives' \ | grep -v '^--glob-archives' \
| grep -v '^--match-archives' \
| grep -v '^--last' \ | grep -v '^--last' \
| grep -v '^--format' \ | grep -v '^--format' \
| grep -v '^--patterns-from' \ | grep -v '^--patterns-from' \

View File

@ -450,7 +450,7 @@ def test_parse_arguments_disallows_json_with_both_rinfo_and_info():
module.parse_arguments('rinfo', 'info', '--json') module.parse_arguments('rinfo', 'info', '--json')
def test_parse_arguments_disallows_transfer_with_both_archive_and_glob_archives(): def test_parse_arguments_disallows_transfer_with_both_archive_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
with pytest.raises(ValueError): with pytest.raises(ValueError):
@ -460,16 +460,16 @@ def test_parse_arguments_disallows_transfer_with_both_archive_and_glob_archives(
'source.borg', 'source.borg',
'--archive', '--archive',
'foo', 'foo',
'--glob-archives', '--match-archives',
'*bar', 'sh:*bar',
) )
def test_parse_arguments_disallows_info_with_both_archive_and_glob_archives(): def test_parse_arguments_disallows_info_with_both_archive_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
with pytest.raises(ValueError): with pytest.raises(ValueError):
module.parse_arguments('info', '--archive', 'foo', '--glob-archives', '*bar') module.parse_arguments('info', '--archive', 'foo', '--match-archives', 'sh:*bar')
def test_parse_arguments_disallows_info_with_both_archive_and_prefix(): def test_parse_arguments_disallows_info_with_both_archive_and_prefix():
@ -479,11 +479,11 @@ def test_parse_arguments_disallows_info_with_both_archive_and_prefix():
module.parse_arguments('info', '--archive', 'foo', '--prefix', 'bar') module.parse_arguments('info', '--archive', 'foo', '--prefix', 'bar')
def test_parse_arguments_disallows_info_with_both_prefix_and_glob_archives(): def test_parse_arguments_disallows_info_with_both_prefix_and_match_archives():
flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default']) flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
with pytest.raises(ValueError): with pytest.raises(ValueError):
module.parse_arguments('info', '--prefix', 'foo', '--glob-archives', '*bar') module.parse_arguments('info', '--prefix', 'foo', '--match-archives', 'sh:*bar')
def test_parse_arguments_check_only_extract_does_not_raise_extract_subparser_error(): def test_parse_arguments_check_only_extract_does_not_raise_extract_subparser_error():

View File

@ -188,95 +188,137 @@ def test_filter_checks_on_frequency_restains_check_with_unelapsed_frequency_and_
def test_make_check_flags_with_repository_check_returns_flag(): def test_make_check_flags_with_repository_check_returns_flag():
flags = module.make_check_flags(('repository',)) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('repository',))
assert flags == ('--repository-only',) assert flags == ('--repository-only',)
def test_make_check_flags_with_archives_check_returns_flag(): def test_make_check_flags_with_archives_check_returns_flag():
flags = module.make_check_flags(('archives',)) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('archives',))
assert flags == ('--archives-only',) assert flags == ('--archives-only',)
def test_make_check_flags_with_data_check_returns_flag_and_implies_archives(): def test_make_check_flags_with_data_check_returns_flag_and_implies_archives():
flags = module.make_check_flags(('data',)) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('data',))
assert flags == ('--archives-only', '--verify-data',) assert flags == ('--archives-only', '--verify-data',)
def test_make_check_flags_with_extract_omits_extract_flag(): def test_make_check_flags_with_extract_omits_extract_flag():
flags = module.make_check_flags(('extract',)) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('extract',))
assert flags == () assert flags == ()
def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only(): def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only():
flags = module.make_check_flags(('repository', 'data',)) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('repository', 'data',))
assert flags == ('--verify-data',) assert flags == ('--verify-data',)
def test_make_check_flags_with_default_checks_and_default_prefix_returns_default_flags(): def test_make_check_flags_with_default_checks_and_default_prefix_returns_default_flags():
flags = module.make_check_flags(('repository', 'archives'), prefix=module.DEFAULT_PREFIX) flexmock(module.feature).should_receive('available').and_return(True)
assert flags == ('--glob-archives', f'{module.DEFAULT_PREFIX}*') flags = module.make_check_flags(
'1.2.3', ('repository', 'archives'), prefix=module.DEFAULT_PREFIX
)
assert flags == ('--match-archives', f'sh:{module.DEFAULT_PREFIX}*')
def test_make_check_flags_with_all_checks_and_default_prefix_returns_default_flags(): def test_make_check_flags_with_all_checks_and_default_prefix_returns_default_flags():
flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags( flags = module.make_check_flags(
('repository', 'archives', 'extract'), prefix=module.DEFAULT_PREFIX '1.2.3', ('repository', 'archives', 'extract'), prefix=module.DEFAULT_PREFIX
)
assert flags == ('--match-archives', f'sh:{module.DEFAULT_PREFIX}*')
def test_make_check_flags_with_all_checks_and_default_prefix_without_borg_features_returns_glob_archives_flags():
flexmock(module.feature).should_receive('available').and_return(False)
flags = module.make_check_flags(
'1.2.3', ('repository', 'archives', 'extract'), prefix=module.DEFAULT_PREFIX
) )
assert flags == ('--glob-archives', f'{module.DEFAULT_PREFIX}*') assert flags == ('--glob-archives', f'{module.DEFAULT_PREFIX}*')
def test_make_check_flags_with_archives_check_and_last_includes_last_flag(): def test_make_check_flags_with_archives_check_and_last_includes_last_flag():
flags = module.make_check_flags(('archives',), check_last=3) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('archives',), check_last=3)
assert flags == ('--archives-only', '--last', '3') assert flags == ('--archives-only', '--last', '3')
def test_make_check_flags_with_repository_check_and_last_omits_last_flag(): def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
flags = module.make_check_flags(('repository',), check_last=3) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('repository',), check_last=3)
assert flags == ('--repository-only',) assert flags == ('--repository-only',)
def test_make_check_flags_with_default_checks_and_last_includes_last_flag(): def test_make_check_flags_with_default_checks_and_last_includes_last_flag():
flags = module.make_check_flags(('repository', 'archives'), check_last=3) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('repository', 'archives'), check_last=3)
assert flags == ('--last', '3') assert flags == ('--last', '3')
def test_make_check_flags_with_archives_check_and_prefix_includes_glob_archives_flag(): def test_make_check_flags_with_archives_check_and_prefix_includes_match_archives_flag():
flags = module.make_check_flags(('archives',), prefix='foo-') flexmock(module.feature).should_receive('available').and_return(True)
assert flags == ('--archives-only', '--glob-archives', 'foo-*') flags = module.make_check_flags('1.2.3', ('archives',), prefix='foo-')
assert flags == ('--archives-only', '--match-archives', 'sh:foo-*')
def test_make_check_flags_with_archives_check_and_empty_prefix_omits_glob_archives_flag(): def test_make_check_flags_with_archives_check_and_empty_prefix_omits_match_archives_flag():
flags = module.make_check_flags(('archives',), prefix='') flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('archives',), prefix='')
assert flags == ('--archives-only',) assert flags == ('--archives-only',)
def test_make_check_flags_with_archives_check_and_none_prefix_omits_glob_archives_flag(): def test_make_check_flags_with_archives_check_and_none_prefix_omits_match_archives_flag():
flags = module.make_check_flags(('archives',), prefix=None) flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('archives',), prefix=None)
assert flags == ('--archives-only',) assert flags == ('--archives-only',)
def test_make_check_flags_with_repository_check_and_prefix_omits_glob_archives_flag(): def test_make_check_flags_with_repository_check_and_prefix_omits_match_archives_flag():
flags = module.make_check_flags(('repository',), prefix='foo-') flexmock(module.feature).should_receive('available').and_return(True)
flags = module.make_check_flags('1.2.3', ('repository',), prefix='foo-')
assert flags == ('--repository-only',) assert flags == ('--repository-only',)
def test_make_check_flags_with_default_checks_and_prefix_includes_glob_archives_flag(): def test_make_check_flags_with_default_checks_and_prefix_includes_match_archives_flag():
flags = module.make_check_flags(('repository', 'archives'), prefix='foo-') flexmock(module.feature).should_receive('available').and_return(True)
assert flags == ('--glob-archives', 'foo-*') flags = module.make_check_flags('1.2.3', ('repository', 'archives'), prefix='foo-')
assert flags == ('--match-archives', 'sh:foo-*')
def test_read_check_time_does_not_raise(): def test_read_check_time_does_not_raise():
@ -369,7 +411,7 @@ def test_check_archives_calls_borg_with_parameters(checks):
'{"repository": {"id": "repo"}}' '{"repository": {"id": "repo"}}'
) )
flexmock(module).should_receive('make_check_flags').with_args( flexmock(module).should_receive('make_check_flags').with_args(
checks, check_last, module.DEFAULT_PREFIX '1.2.3', checks, check_last, module.DEFAULT_PREFIX
).and_return(()) ).and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg', 'check', 'repo')) insert_execute_command_mock(('borg', 'check', 'repo'))
@ -523,7 +565,7 @@ def test_check_archives_with_local_path_calls_borg_via_local_path():
'{"repository": {"id": "repo"}}' '{"repository": {"id": "repo"}}'
) )
flexmock(module).should_receive('make_check_flags').with_args( flexmock(module).should_receive('make_check_flags').with_args(
checks, check_last, module.DEFAULT_PREFIX '1.2.3', checks, check_last, module.DEFAULT_PREFIX
).and_return(()) ).and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg1', 'check', 'repo')) insert_execute_command_mock(('borg1', 'check', 'repo'))
@ -550,7 +592,7 @@ def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters(
'{"repository": {"id": "repo"}}' '{"repository": {"id": "repo"}}'
) )
flexmock(module).should_receive('make_check_flags').with_args( flexmock(module).should_receive('make_check_flags').with_args(
checks, check_last, module.DEFAULT_PREFIX '1.2.3', checks, check_last, module.DEFAULT_PREFIX
).and_return(()) ).and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo')) insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo'))
@ -577,7 +619,7 @@ def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
'{"repository": {"id": "repo"}}' '{"repository": {"id": "repo"}}'
) )
flexmock(module).should_receive('make_check_flags').with_args( flexmock(module).should_receive('make_check_flags').with_args(
checks, check_last, module.DEFAULT_PREFIX '1.2.3', checks, check_last, module.DEFAULT_PREFIX
).and_return(()) ).and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo')) insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo'))
@ -604,7 +646,7 @@ def test_check_archives_with_retention_prefix():
'{"repository": {"id": "repo"}}' '{"repository": {"id": "repo"}}'
) )
flexmock(module).should_receive('make_check_flags').with_args( flexmock(module).should_receive('make_check_flags').with_args(
checks, check_last, prefix '1.2.3', checks, check_last, prefix
).and_return(()) ).and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg', 'check', 'repo')) insert_execute_command_mock(('borg', 'check', 'repo'))

View File

@ -137,16 +137,16 @@ def test_display_archives_info_with_json_calls_borg_with_json_parameter():
assert json_output == '[]' assert json_output == '[]'
def test_display_archives_info_with_archive_calls_borg_with_glob_archives_parameter(): def test_display_archives_info_with_archive_calls_borg_with_match_archives_parameter():
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_flags').with_args(
'glob-archives', 'archive' 'match-archives', 'archive'
).and_return(('--glob-archives', 'archive')) ).and_return(('--match-archives', 'archive'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'info', '--repo', 'repo', '--glob-archives', 'archive'), ('borg', 'info', '--repo', 'repo', '--match-archives', 'archive'),
output_log_level=logging.WARNING, output_log_level=logging.WARNING,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -229,16 +229,16 @@ def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_paramete
) )
def test_display_archives_info_with_prefix_calls_borg_with_glob_archives_parameters(): def test_display_archives_info_with_prefix_calls_borg_with_match_archives_parameters():
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_flags').with_args(
'glob-archives', 'foo*' 'match-archives', 'sh:foo*'
).and_return(('--glob-archives', 'foo*')) ).and_return(('--match-archives', 'sh:foo*'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'info', '--glob-archives', 'foo*', '--repo', 'repo'), ('borg', 'info', '--match-archives', 'sh:foo*', '--repo', 'repo'),
output_log_level=logging.WARNING, output_log_level=logging.WARNING,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -252,7 +252,7 @@ def test_display_archives_info_with_prefix_calls_borg_with_glob_archives_paramet
) )
@pytest.mark.parametrize('argument_name', ('glob_archives', 'sort_by', 'first', 'last')) @pytest.mark.parametrize('argument_name', ('match_archives', 'sort_by', 'first', 'last'))
def test_display_archives_info_passes_through_arguments_to_borg(argument_name): def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
flag_name = f"--{argument_name.replace('_', ' ')}" flag_name = f"--{argument_name.replace('_', ' ')}"
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())

View File

@ -192,7 +192,7 @@ def test_make_list_command_includes_short():
'argument_name', 'argument_name',
( (
'prefix', 'prefix',
'glob_archives', 'match_archives',
'sort_by', 'sort_by',
'first', 'first',
'last', 'last',
@ -260,7 +260,7 @@ def test_list_archive_calls_borg_with_parameters():
json=False, json=False,
find_paths=None, find_paths=None,
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -313,7 +313,7 @@ def test_list_archive_calls_borg_with_local_path():
json=False, json=False,
find_paths=None, find_paths=None,
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -353,7 +353,7 @@ def test_list_archive_calls_borg_multiple_times_with_find_paths():
json=False, json=False,
find_paths=['foo.txt'], find_paths=['foo.txt'],
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -400,7 +400,7 @@ def test_list_archive_calls_borg_with_archive():
json=False, json=False,
find_paths=None, find_paths=None,
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -439,7 +439,7 @@ def test_list_archive_without_archive_delegates_to_list_repository():
format=None, format=None,
json=None, json=None,
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -466,7 +466,7 @@ def test_list_archive_with_borg_features_without_archive_delegates_to_list_repos
format=None, format=None,
json=None, json=None,
prefix=None, prefix=None,
glob_archives=None, match_archives=None,
sort_by=None, sort_by=None,
first=None, first=None,
last=None, last=None,
@ -487,12 +487,12 @@ def test_list_archive_with_borg_features_without_archive_delegates_to_list_repos
@pytest.mark.parametrize( @pytest.mark.parametrize(
'archive_filter_flag', ('prefix', 'glob_archives', 'sort_by', 'first', 'last',), 'archive_filter_flag', ('prefix', 'match_archives', 'sort_by', 'first', 'last',),
) )
def test_list_archive_with_archive_ignores_archive_filter_flag(archive_filter_flag,): def test_list_archive_with_archive_ignores_archive_filter_flag(archive_filter_flag,):
default_filter_flags = { default_filter_flags = {
'prefix': None, 'prefix': None,
'glob_archives': None, 'match_archives': None,
'sort_by': None, 'sort_by': None,
'first': None, 'first': None,
'last': None, 'last': None,
@ -532,14 +532,14 @@ def test_list_archive_with_archive_ignores_archive_filter_flag(archive_filter_fl
@pytest.mark.parametrize( @pytest.mark.parametrize(
'archive_filter_flag', ('prefix', 'glob_archives', 'sort_by', 'first', 'last',), 'archive_filter_flag', ('prefix', 'match_archives', 'sort_by', 'first', 'last',),
) )
def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes_it_to_rlist( def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes_it_to_rlist(
archive_filter_flag, archive_filter_flag,
): ):
default_filter_flags = { default_filter_flags = {
'prefix': None, 'prefix': None,
'glob_archives': None, 'match_archives': None,
'sort_by': None, 'sort_by': None,
'first': None, 'first': None,
'last': None, 'last': None,

View File

@ -31,11 +31,11 @@ def test_mount_archive_calls_borg_with_required_flags():
) )
def test_mount_archive_with_borg_features_calls_borg_with_repository_and_glob_archives_flags(): def test_mount_archive_with_borg_features_calls_borg_with_repository_and_match_archives_flags():
flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.feature).should_receive('available').and_return(True)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo',))
insert_execute_command_mock( insert_execute_command_mock(
('borg', 'mount', '--repo', 'repo', '--glob-archives', 'archive', '/mnt') ('borg', 'mount', '--repo', 'repo', '--match-archives', 'archive', '/mnt')
) )
module.mount_archive( module.mount_archive(

View File

@ -23,16 +23,29 @@ BASE_PRUNE_FLAGS = (('--keep-daily', '1'), ('--keep-weekly', '2'), ('--keep-mont
def test_make_prune_flags_returns_flags_from_config_plus_default_prefix_glob(): def test_make_prune_flags_returns_flags_from_config_plus_default_prefix_glob():
retention_config = OrderedDict((('keep_daily', 1), ('keep_weekly', 2), ('keep_monthly', 3))) retention_config = OrderedDict((('keep_daily', 1), ('keep_weekly', 2), ('keep_monthly', 3)))
flexmock(module.feature).should_receive('available').and_return(True)
result = module.make_prune_flags(retention_config) result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
assert tuple(result) == BASE_PRUNE_FLAGS + (('--glob-archives', '{hostname}-*'),) assert tuple(result) == BASE_PRUNE_FLAGS + (('--match-archives', 'sh:{hostname}-*'),)
def test_make_prune_flags_accepts_prefix_with_placeholders(): def test_make_prune_flags_accepts_prefix_with_placeholders():
retention_config = OrderedDict((('keep_daily', 1), ('prefix', 'Documents_{hostname}-{now}'))) retention_config = OrderedDict((('keep_daily', 1), ('prefix', 'Documents_{hostname}-{now}')))
flexmock(module.feature).should_receive('available').and_return(True)
result = module.make_prune_flags(retention_config) result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
expected = (('--keep-daily', '1'), ('--match-archives', 'sh:Documents_{hostname}-{now}*'))
assert tuple(result) == expected
def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives():
retention_config = OrderedDict((('keep_daily', 1), ('prefix', 'Documents_{hostname}-{now}')))
flexmock(module.feature).should_receive('available').and_return(False)
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
expected = (('--keep-daily', '1'), ('--glob-archives', 'Documents_{hostname}-{now}*')) expected = (('--keep-daily', '1'), ('--glob-archives', 'Documents_{hostname}-{now}*'))
@ -41,8 +54,9 @@ def test_make_prune_flags_accepts_prefix_with_placeholders():
def test_make_prune_flags_treats_empty_prefix_as_no_prefix(): def test_make_prune_flags_treats_empty_prefix_as_no_prefix():
retention_config = OrderedDict((('keep_daily', 1), ('prefix', ''))) retention_config = OrderedDict((('keep_daily', 1), ('prefix', '')))
flexmock(module.feature).should_receive('available').and_return(True)
result = module.make_prune_flags(retention_config) result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
expected = (('--keep-daily', '1'),) expected = (('--keep-daily', '1'),)
@ -51,8 +65,9 @@ def test_make_prune_flags_treats_empty_prefix_as_no_prefix():
def test_make_prune_flags_treats_none_prefix_as_no_prefix(): def test_make_prune_flags_treats_none_prefix_as_no_prefix():
retention_config = OrderedDict((('keep_daily', 1), ('prefix', None))) retention_config = OrderedDict((('keep_daily', 1), ('prefix', None)))
flexmock(module.feature).should_receive('available').and_return(True)
result = module.make_prune_flags(retention_config) result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
expected = (('--keep-daily', '1'),) expected = (('--keep-daily', '1'),)
@ -63,10 +78,7 @@ PRUNE_COMMAND = ('borg', 'prune', '--keep-daily', '1', '--keep-weekly', '2', '--
def test_prune_archives_calls_borg_with_parameters(): def test_prune_archives_calls_borg_with_parameters():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('repo',), logging.INFO)
@ -74,16 +86,13 @@ def test_prune_archives_calls_borg_with_parameters():
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_log_info_calls_borg_with_info_parameter(): def test_prune_archives_with_log_info_calls_borg_with_info_parameter():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--info', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--info', 'repo'), logging.INFO)
insert_logging_mock(logging.INFO) insert_logging_mock(logging.INFO)
@ -92,16 +101,13 @@ def test_prune_archives_with_log_info_calls_borg_with_info_parameter():
repository='repo', repository='repo',
storage_config={}, storage_config={},
dry_run=False, dry_run=False,
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_log_debug_calls_borg_with_debug_parameter(): def test_prune_archives_with_log_debug_calls_borg_with_debug_parameter():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO)
insert_logging_mock(logging.DEBUG) insert_logging_mock(logging.DEBUG)
@ -110,16 +116,13 @@ def test_prune_archives_with_log_debug_calls_borg_with_debug_parameter():
repository='repo', repository='repo',
storage_config={}, storage_config={},
dry_run=False, dry_run=False,
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_dry_run_calls_borg_with_dry_run_parameter(): def test_prune_archives_with_dry_run_calls_borg_with_dry_run_parameter():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--dry-run', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--dry-run', 'repo'), logging.INFO)
@ -127,16 +130,13 @@ def test_prune_archives_with_dry_run_calls_borg_with_dry_run_parameter():
repository='repo', repository='repo',
storage_config={}, storage_config={},
dry_run=True, dry_run=True,
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_local_path_calls_borg_via_local_path(): def test_prune_archives_with_local_path_calls_borg_via_local_path():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(('borg1',) + PRUNE_COMMAND[1:] + ('repo',), logging.INFO) insert_execute_command_mock(('borg1',) + PRUNE_COMMAND[1:] + ('repo',), logging.INFO)
@ -144,17 +144,14 @@ def test_prune_archives_with_local_path_calls_borg_via_local_path():
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
local_path='borg1', local_path='borg1',
) )
def test_prune_archives_with_remote_path_calls_borg_with_remote_path_parameters(): def test_prune_archives_with_remote_path_calls_borg_with_remote_path_parameters():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO)
@ -162,17 +159,14 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_parameters(
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
remote_path='borg1', remote_path='borg1',
) )
def test_prune_archives_with_stats_calls_borg_with_stats_parameter_and_warning_output_log_level(): def test_prune_archives_with_stats_calls_borg_with_stats_parameter_and_warning_output_log_level():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), logging.WARNING) insert_execute_command_mock(PRUNE_COMMAND + ('--stats', 'repo'), logging.WARNING)
@ -180,17 +174,14 @@ def test_prune_archives_with_stats_calls_borg_with_stats_parameter_and_warning_o
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
stats=True, stats=True,
) )
def test_prune_archives_with_stats_and_log_info_calls_borg_with_stats_parameter_and_info_output_log_level(): def test_prune_archives_with_stats_and_log_info_calls_borg_with_stats_parameter_and_info_output_log_level():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_logging_mock(logging.INFO) insert_logging_mock(logging.INFO)
insert_execute_command_mock(PRUNE_COMMAND + ('--stats', '--info', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--stats', '--info', 'repo'), logging.INFO)
@ -199,17 +190,14 @@ def test_prune_archives_with_stats_and_log_info_calls_borg_with_stats_parameter_
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
stats=True, stats=True,
) )
def test_prune_archives_with_files_calls_borg_with_list_parameter_and_warning_output_log_level(): def test_prune_archives_with_files_calls_borg_with_list_parameter_and_warning_output_log_level():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), logging.WARNING) insert_execute_command_mock(PRUNE_COMMAND + ('--list', 'repo'), logging.WARNING)
@ -217,17 +205,14 @@ def test_prune_archives_with_files_calls_borg_with_list_parameter_and_warning_ou
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
list_archives=True, list_archives=True,
) )
def test_prune_archives_with_files_and_log_info_calls_borg_with_list_parameter_and_info_output_log_level(): def test_prune_archives_with_files_and_log_info_calls_borg_with_list_parameter_and_info_output_log_level():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_logging_mock(logging.INFO) insert_logging_mock(logging.INFO)
insert_execute_command_mock(PRUNE_COMMAND + ('--info', '--list', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--info', '--list', 'repo'), logging.INFO)
@ -236,7 +221,7 @@ def test_prune_archives_with_files_and_log_info_calls_borg_with_list_parameter_a
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={}, storage_config={},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
list_archives=True, list_archives=True,
) )
@ -244,10 +229,7 @@ def test_prune_archives_with_files_and_log_info_calls_borg_with_list_parameter_a
def test_prune_archives_with_umask_calls_borg_with_umask_parameters(): def test_prune_archives_with_umask_calls_borg_with_umask_parameters():
storage_config = {'umask': '077'} storage_config = {'umask': '077'}
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--umask', '077', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--umask', '077', 'repo'), logging.INFO)
@ -255,17 +237,14 @@ def test_prune_archives_with_umask_calls_borg_with_umask_parameters():
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config=storage_config, storage_config=storage_config,
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_parameters(): def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
storage_config = {'lock_wait': 5} storage_config = {'lock_wait': 5}
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO)
@ -273,16 +252,13 @@ def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config=storage_config, storage_config=storage_config,
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options(): def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options():
retention_config = flexmock() flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
flexmock(module).should_receive('make_prune_flags').with_args(retention_config).and_return(
BASE_PRUNE_FLAGS
)
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
insert_execute_command_mock(PRUNE_COMMAND + ('--extra', '--options', 'repo'), logging.INFO) insert_execute_command_mock(PRUNE_COMMAND + ('--extra', '--options', 'repo'), logging.INFO)
@ -290,6 +266,6 @@ def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options():
dry_run=False, dry_run=False,
repository='repo', repository='repo',
storage_config={'extra_borg_options': {'prune': '--extra --options'}}, storage_config={'extra_borg_options': {'prune': '--extra --options'}},
retention_config=retention_config, retention_config=flexmock(),
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )

View File

@ -41,11 +41,11 @@ def test_resolve_archive_name_calls_borg_with_parameters():
) )
def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter(): def test_resolve_archive_name_with_log_info_calls_borg_without_info_parameter():
expected_archive = 'archive-name' expected_archive = 'archive-name'
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'list', '--info') + BORG_LIST_LATEST_ARGUMENTS, ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS,
output_log_level=None, output_log_level=None,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -58,11 +58,11 @@ def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter():
) )
def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter(): def test_resolve_archive_name_with_log_debug_calls_borg_without_debug_parameter():
expected_archive = 'archive-name' expected_archive = 'archive-name'
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'list', '--debug', '--show-rc') + BORG_LIST_LATEST_ARGUMENTS, ('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS,
output_log_level=None, output_log_level=None,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -273,9 +273,9 @@ def test_make_rlist_command_includes_remote_path():
assert command == ('borg', 'list', '--remote-path', 'borg2', 'repo') assert command == ('borg', 'list', '--remote-path', 'borg2', 'repo')
def test_make_rlist_command_transforms_prefix_into_glob_archives(): def test_make_rlist_command_transforms_prefix_into_match_archives():
flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return( flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return(
('--glob-archives', 'foo*') ('--match-archives', 'sh:foo*')
) )
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',)) flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
@ -287,7 +287,7 @@ def test_make_rlist_command_transforms_prefix_into_glob_archives():
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix='foo'), rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix='foo'),
) )
assert command == ('borg', 'list', '--glob-archives', 'foo*', 'repo') assert command == ('borg', 'list', '--match-archives', 'sh:foo*', 'repo')
def test_make_rlist_command_includes_short(): def test_make_rlist_command_includes_short():
@ -308,7 +308,7 @@ def test_make_rlist_command_includes_short():
@pytest.mark.parametrize( @pytest.mark.parametrize(
'argument_name', 'argument_name',
( (
'glob_archives', 'match_archives',
'sort_by', 'sort_by',
'first', 'first',
'last', 'last',

View File

@ -25,7 +25,7 @@ def test_transfer_archives_calls_borg_with_flags():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
) )
@ -49,7 +49,7 @@ def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
) )
@ -70,7 +70,7 @@ def test_transfer_archives_with_log_info_calls_borg_with_info_flag():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
) )
@ -92,20 +92,20 @@ def test_transfer_archives_with_log_debug_calls_borg_with_debug_flag():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
) )
def test_transfer_archives_with_archive_calls_borg_with_glob_archives_flag(): def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag():
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_flags').with_args(
'glob-archives', 'archive' 'match-archives', 'archive'
).and_return(('--glob-archives', 'archive')) ).and_return(('--match-archives', 'archive'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'transfer', '--glob-archives', 'archive', '--repo', 'repo'), ('borg', 'transfer', '--match-archives', 'archive', '--repo', 'repo'),
output_log_level=logging.WARNING, output_log_level=logging.WARNING,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -116,20 +116,20 @@ def test_transfer_archives_with_archive_calls_borg_with_glob_archives_flag():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive='archive', glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive='archive', match_archives=None, source_repository=None),
) )
def test_transfer_archives_with_glob_archives_calls_borg_with_glob_archives_flag(): def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_flag():
flexmock(module.flags).should_receive('make_flags').and_return(()) flexmock(module.flags).should_receive('make_flags').and_return(())
flexmock(module.flags).should_receive('make_flags').with_args( flexmock(module.flags).should_receive('make_flags').with_args(
'glob-archives', 'foo*' 'match-archives', 'sh:foo*'
).and_return(('--glob-archives', 'foo*')) ).and_return(('--match-archives', 'sh:foo*'))
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(()) flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo')) flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
flexmock(module.environment).should_receive('make_environment') flexmock(module.environment).should_receive('make_environment')
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'transfer', '--glob-archives', 'foo*', '--repo', 'repo'), ('borg', 'transfer', '--match-archives', 'sh:foo*', '--repo', 'repo'),
output_log_level=logging.WARNING, output_log_level=logging.WARNING,
borg_local_path='borg', borg_local_path='borg',
extra_environment=None, extra_environment=None,
@ -140,7 +140,7 @@ def test_transfer_archives_with_glob_archives_calls_borg_with_glob_archives_flag
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives='foo*', source_repository=None), transfer_arguments=flexmock(archive=None, match_archives='sh:foo*', source_repository=None),
) )
@ -161,7 +161,7 @@ def test_transfer_archives_with_local_path_calls_borg_via_local_path():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
local_path='borg2', local_path='borg2',
) )
@ -186,7 +186,7 @@ def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags():
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
remote_path='borg2', remote_path='borg2',
) )
@ -212,7 +212,7 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags():
repository='repo', repository='repo',
storage_config=storage_config, storage_config=storage_config,
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository=None), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository=None),
) )
@ -238,7 +238,7 @@ def test_transfer_archives_passes_through_arguments_to_borg(argument_name):
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock( transfer_arguments=flexmock(
archive=None, glob_archives=None, source_repository=None, **{argument_name: 'value'} archive=None, match_archives=None, source_repository=None, **{argument_name: 'value'}
), ),
) )
@ -263,5 +263,5 @@ def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_fla
repository='repo', repository='repo',
storage_config={}, storage_config={},
local_borg_version='2.3.4', local_borg_version='2.3.4',
transfer_arguments=flexmock(archive=None, glob_archives=None, source_repository='other'), transfer_arguments=flexmock(archive=None, match_archives=None, source_repository='other'),
) )