merge
This commit is contained in:
commit
32ab17fa46
27 changed files with 542 additions and 149 deletions
|
@ -24,6 +24,8 @@ clone:
|
|||
steps:
|
||||
- name: build
|
||||
image: alpine:3.13
|
||||
environment:
|
||||
TEST_CONTAINER: true
|
||||
pull: always
|
||||
commands:
|
||||
- scripts/run-full-tests
|
||||
|
|
9
NEWS
9
NEWS
|
@ -1,3 +1,12 @@
|
|||
1.7.11.dev0
|
||||
* #479: Automatically use the "archive_name_format" option to filter which archives get used for
|
||||
borgmatic actions that operate on multiple archives. See the documentation for more information:
|
||||
https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#archive-naming
|
||||
* #479: The "prefix" options have been deprecated in favor of the new "archive_name_format"
|
||||
auto-matching behavior (see above).
|
||||
* #662: Fix regression in which "check_repositories" option failed to match repositories.
|
||||
* #663: Fix regression in which the "transfer" action produced a traceback.
|
||||
|
||||
1.7.10
|
||||
* #396: When a database command errors, display and log the error message instead of swallowing it.
|
||||
* #501: Optionally error if a source directory does not exist via "source_directories_must_exist"
|
||||
|
|
|
@ -17,10 +17,10 @@ def run_transfer(
|
|||
'''
|
||||
Run the "transfer" action for the given repository.
|
||||
'''
|
||||
logger.info(f'{repository}: Transferring archives to repository')
|
||||
logger.info(f'{repository["path"]}: Transferring archives to repository')
|
||||
borgmatic.borg.transfer.transfer_archives(
|
||||
global_arguments.dry_run,
|
||||
repository,
|
||||
repository['path'],
|
||||
storage,
|
||||
local_borg_version,
|
||||
transfer_arguments,
|
||||
|
|
|
@ -12,7 +12,6 @@ DEFAULT_CHECKS = (
|
|||
{'name': 'repository', 'frequency': '1 month'},
|
||||
{'name': 'archives', 'frequency': '1 month'},
|
||||
)
|
||||
DEFAULT_PREFIX = '{hostname}-' # noqa: FS003
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -146,9 +145,10 @@ def filter_checks_on_frequency(
|
|||
return tuple(filtered_checks)
|
||||
|
||||
|
||||
def make_check_flags(local_borg_version, checks, check_last=None, prefix=None):
|
||||
def make_check_flags(local_borg_version, storage_config, checks, check_last=None, prefix=None):
|
||||
'''
|
||||
Given the local Borg version and a parsed sequence of checks, transform the checks into tuple of
|
||||
Given the local Borg version, a storge configuration dict, a parsed sequence of checks, the
|
||||
check last value, and a consistency check prefix, transform the checks into tuple of
|
||||
command-line flags.
|
||||
|
||||
For example, given parsed checks of:
|
||||
|
@ -174,10 +174,19 @@ def make_check_flags(local_borg_version, checks, check_last=None, prefix=None):
|
|||
|
||||
if 'archives' in checks:
|
||||
last_flags = ('--last', str(check_last)) if check_last 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 ()
|
||||
match_archives_flags = (
|
||||
(
|
||||
('--match-archives', f'sh:{prefix}*')
|
||||
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version)
|
||||
else ('--glob-archives', f'{prefix}*')
|
||||
)
|
||||
if prefix
|
||||
else (
|
||||
flags.make_match_archives_flags(
|
||||
storage_config.get('archive_name_format'), local_borg_version
|
||||
)
|
||||
)
|
||||
)
|
||||
else:
|
||||
last_flags = ()
|
||||
match_archives_flags = ()
|
||||
|
@ -291,7 +300,7 @@ def check_archives(
|
|||
extra_borg_options = storage_config.get('extra_borg_options', {}).get('check', '')
|
||||
|
||||
if set(checks).intersection({'repository', 'archives', 'data'}):
|
||||
lock_wait = storage_config.get('lock_wait', None)
|
||||
lock_wait = storage_config.get('lock_wait')
|
||||
|
||||
verbosity_flags = ()
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
|
@ -299,12 +308,12 @@ def check_archives(
|
|||
if logger.isEnabledFor(logging.DEBUG):
|
||||
verbosity_flags = ('--debug', '--show-rc')
|
||||
|
||||
prefix = consistency_config.get('prefix', DEFAULT_PREFIX)
|
||||
prefix = consistency_config.get('prefix')
|
||||
|
||||
full_command = (
|
||||
(local_path, 'check')
|
||||
+ (('--repair',) if repair else ())
|
||||
+ make_check_flags(local_borg_version, checks, check_last, prefix)
|
||||
+ make_check_flags(local_borg_version, storage_config, checks, check_last, prefix)
|
||||
+ (('--remote-path', remote_path) if remote_path else ())
|
||||
+ (('--lock-wait', str(lock_wait)) if lock_wait else ())
|
||||
+ verbosity_flags
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import itertools
|
||||
import re
|
||||
|
||||
from borgmatic.borg import feature
|
||||
|
||||
|
@ -56,3 +57,20 @@ def make_repository_archive_flags(repository_path, archive, local_borg_version):
|
|||
if feature.available(feature.Feature.SEPARATE_REPOSITORY_ARCHIVE, local_borg_version)
|
||||
else (f'{repository_path}::{archive}',)
|
||||
)
|
||||
|
||||
|
||||
def make_match_archives_flags(archive_name_format, local_borg_version):
|
||||
'''
|
||||
Return the match archives flags that would match archives created with the given archive name
|
||||
format (if any). This is done by replacing certain archive name format placeholders for
|
||||
ephemeral data (like "{now}") with globs.
|
||||
'''
|
||||
if not archive_name_format:
|
||||
return ()
|
||||
|
||||
match_archives = re.sub(r'\{(now|utcnow|pid)([:%\w\.-]*)\}', '*', archive_name_format)
|
||||
|
||||
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version):
|
||||
return ('--match-archives', f'sh:{match_archives}')
|
||||
else:
|
||||
return ('--glob-archives', f'{match_archives}')
|
||||
|
|
|
@ -44,7 +44,11 @@ def display_archives_info(
|
|||
else flags.make_flags('glob-archives', f'{info_arguments.prefix}*')
|
||||
)
|
||||
if info_arguments.prefix
|
||||
else ()
|
||||
else (
|
||||
flags.make_match_archives_flags(
|
||||
storage_config.get('archive_name_format'), local_borg_version
|
||||
)
|
||||
)
|
||||
)
|
||||
+ flags.make_flags_from_arguments(
|
||||
info_arguments, excludes=('repository', 'archive', 'prefix')
|
||||
|
|
|
@ -7,10 +7,10 @@ from borgmatic.execute import execute_command
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def make_prune_flags(retention_config, local_borg_version):
|
||||
def make_prune_flags(storage_config, retention_config, local_borg_version):
|
||||
'''
|
||||
Given a retention config dict mapping from option name to value, transform it into an iterable of
|
||||
command-line name-value flag pairs.
|
||||
Given a retention config dict mapping from option name to value, transform it into an sequence of
|
||||
command-line flags.
|
||||
|
||||
For example, given a retention config of:
|
||||
|
||||
|
@ -24,7 +24,7 @@ def make_prune_flags(retention_config, local_borg_version):
|
|||
)
|
||||
'''
|
||||
config = retention_config.copy()
|
||||
prefix = config.pop('prefix', '{hostname}-') # noqa: FS003
|
||||
prefix = config.pop('prefix', None)
|
||||
|
||||
if prefix:
|
||||
if feature.available(feature.Feature.MATCH_ARCHIVES, local_borg_version):
|
||||
|
@ -32,10 +32,16 @@ def make_prune_flags(retention_config, local_borg_version):
|
|||
else:
|
||||
config['glob_archives'] = f'{prefix}*'
|
||||
|
||||
return (
|
||||
flag_pairs = (
|
||||
('--' + option_name.replace('_', '-'), str(value)) for option_name, value in config.items()
|
||||
)
|
||||
|
||||
return tuple(
|
||||
element for pair in flag_pairs for element in pair
|
||||
) + flags.make_match_archives_flags(
|
||||
storage_config.get('archive_name_format'), local_borg_version
|
||||
)
|
||||
|
||||
|
||||
def prune_archives(
|
||||
dry_run,
|
||||
|
@ -60,11 +66,7 @@ def prune_archives(
|
|||
|
||||
full_command = (
|
||||
(local_path, 'prune')
|
||||
+ tuple(
|
||||
element
|
||||
for pair in make_prune_flags(retention_config, local_borg_version)
|
||||
for element in pair
|
||||
)
|
||||
+ make_prune_flags(storage_config, retention_config, local_borg_version)
|
||||
+ (('--remote-path', remote_path) if remote_path else ())
|
||||
+ (('--umask', str(umask)) if umask else ())
|
||||
+ (('--lock-wait', str(lock_wait)) if lock_wait else ())
|
||||
|
|
|
@ -94,7 +94,11 @@ def make_rlist_command(
|
|||
else flags.make_flags('glob-archives', f'{rlist_arguments.prefix}*')
|
||||
)
|
||||
if rlist_arguments.prefix
|
||||
else ()
|
||||
else (
|
||||
flags.make_match_archives_flags(
|
||||
storage_config.get('archive_name_format'), local_borg_version
|
||||
)
|
||||
)
|
||||
)
|
||||
+ flags.make_flags_from_arguments(rlist_arguments, excludes=MAKE_FLAGS_EXCLUDES)
|
||||
+ flags.make_repository_flags(repository_path, local_borg_version)
|
||||
|
|
|
@ -34,10 +34,17 @@ def transfer_archives(
|
|||
'match-archives', transfer_arguments.match_archives or transfer_arguments.archive
|
||||
)
|
||||
)
|
||||
+ flags.make_flags_from_arguments(
|
||||
+ (
|
||||
flags.make_flags_from_arguments(
|
||||
transfer_arguments,
|
||||
excludes=('repository', 'source_repository', 'archive', 'match_archives'),
|
||||
)
|
||||
or (
|
||||
flags.make_match_archives_flags(
|
||||
storage_config.get('archive_name_format'), local_borg_version
|
||||
)
|
||||
)
|
||||
)
|
||||
+ flags.make_repository_flags(repository_path, local_borg_version)
|
||||
+ flags.make_flags('other-repo', transfer_arguments.source_repository)
|
||||
+ flags.make_flags('dry-run', dry_run)
|
||||
|
|
|
@ -378,11 +378,9 @@ properties:
|
|||
description: |
|
||||
Name of the archive. Borg placeholders can be used. See the
|
||||
output of "borg help placeholders" for details. Defaults to
|
||||
"{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}". If you specify this
|
||||
option, consider also specifying a prefix in the retention
|
||||
and consistency sections to avoid accidental
|
||||
pruning/checking of archives with different archive name
|
||||
formats.
|
||||
"{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}". When running
|
||||
actions like rlist, info, or check, borgmatic automatically
|
||||
tries to match only archives created with this name format.
|
||||
example: "{hostname}-documents-{now}"
|
||||
relocated_repo_access_is_ok:
|
||||
type: boolean
|
||||
|
@ -477,10 +475,12 @@ properties:
|
|||
prefix:
|
||||
type: string
|
||||
description: |
|
||||
When pruning, only consider archive names starting with this
|
||||
prefix. Borg placeholders can be used. See the output of
|
||||
"borg help placeholders" for details. Defaults to
|
||||
"{hostname}-". Use an empty value to disable the default.
|
||||
Deprecated. When pruning, only consider archive names
|
||||
starting with this prefix. Borg placeholders can be used.
|
||||
See the output of "borg help placeholders" for details.
|
||||
If a prefix is not specified, borgmatic defaults to
|
||||
matching archives based on the archive_name_format (see
|
||||
above).
|
||||
example: sourcehostname
|
||||
consistency:
|
||||
type: object
|
||||
|
@ -538,12 +538,12 @@ properties:
|
|||
items:
|
||||
type: string
|
||||
description: |
|
||||
Paths to a subset of the repositories in the location
|
||||
section on which to run consistency checks. Handy in case
|
||||
some of your repositories are very large, and so running
|
||||
consistency checks on them would take too long. Defaults to
|
||||
running consistency checks on all repositories configured in
|
||||
the location section.
|
||||
Paths or labels for a subset of the repositories in the
|
||||
location section on which to run consistency checks. Handy
|
||||
in case some of your repositories are very large, and so
|
||||
running consistency checks on them would take too long.
|
||||
Defaults to running consistency checks on all repositories
|
||||
configured in the location section.
|
||||
example:
|
||||
- user@backupserver:sourcehostname.borg
|
||||
check_last:
|
||||
|
@ -556,11 +556,12 @@ properties:
|
|||
prefix:
|
||||
type: string
|
||||
description: |
|
||||
When performing the "archives" check, only consider archive
|
||||
names starting with this prefix. Borg placeholders can be
|
||||
used. See the output of "borg help placeholders" for
|
||||
details. Defaults to "{hostname}-". Use an empty value to
|
||||
disable the default.
|
||||
Deprecated. When performing the "archives" check, only
|
||||
consider archive names starting with this prefix. Borg
|
||||
placeholders can be used. See the output of "borg help
|
||||
placeholders" for details. If a prefix is not specified,
|
||||
borgmatic defaults to matching archives based on the
|
||||
archive_name_format (see above).
|
||||
example: sourcehostname
|
||||
output:
|
||||
type: object
|
||||
|
|
|
@ -69,7 +69,10 @@ def apply_logical_validation(config_filename, parsed_configuration):
|
|||
location_repositories = parsed_configuration.get('location', {}).get('repositories')
|
||||
check_repositories = parsed_configuration.get('consistency', {}).get('check_repositories', [])
|
||||
for repository in check_repositories:
|
||||
if repository not in location_repositories:
|
||||
if not any(
|
||||
repositories_match(repository, config_repository)
|
||||
for config_repository in location_repositories
|
||||
):
|
||||
raise Validation_error(
|
||||
config_filename,
|
||||
(
|
||||
|
|
|
@ -25,7 +25,7 @@ so that you can run borgmatic commands while you're hacking on them to
|
|||
make sure your changes work.
|
||||
|
||||
```bash
|
||||
cd borgmatic/
|
||||
cd borgmatic
|
||||
pip3 install --user --editable .
|
||||
```
|
||||
|
||||
|
@ -51,7 +51,6 @@ pip3 install --user tox
|
|||
Finally, to actually run tests, run:
|
||||
|
||||
```bash
|
||||
cd borgmatic
|
||||
tox
|
||||
```
|
||||
|
||||
|
|
|
@ -54,6 +54,71 @@ choice](https://torsion.org/borgmatic/docs/how-to/set-up-backups/#autopilot),
|
|||
each entry using borgmatic's `--config` flag instead of relying on
|
||||
`/etc/borgmatic.d`.
|
||||
|
||||
|
||||
## Archive naming
|
||||
|
||||
If you've got multiple borgmatic configuration files, you might want to create
|
||||
archives with different naming schemes for each one. This is especially handy
|
||||
if each configuration file is backing up to the same Borg repository but you
|
||||
still want to be able to distinguish backup archives for one application from
|
||||
another.
|
||||
|
||||
borgmatic supports this use case with an `archive_name_format` option. The
|
||||
idea is that you define a string format containing a number of [Borg
|
||||
placeholders](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-placeholders),
|
||||
and borgmatic uses that format to name any new archive it creates. For
|
||||
instance:
|
||||
|
||||
```yaml
|
||||
location:
|
||||
...
|
||||
archive_name_format: home-directories-{now}
|
||||
```
|
||||
|
||||
This means that when borgmatic creates an archive, its name will start with
|
||||
the string `home-directories-` and end with a timestamp for its creation time.
|
||||
If `archive_name_format` is unspecified, the default is
|
||||
`{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}`, meaning your system hostname plus a
|
||||
timestamp in a particular format.
|
||||
|
||||
<span class="minilink minilink-addedin">New in version 1.7.11</span> borgmatic
|
||||
uses the `archive_name_format` option to automatically limit which archives
|
||||
get used for actions operating on multiple archives. This prevents, for
|
||||
instance, duplicate archives from showing up in `rlist` or `info` results—even
|
||||
if the same repository appears in multiple borgmatic configuration files. To
|
||||
take advantage of this feature, simply use a different `archive_name_format`
|
||||
in each configuration file.
|
||||
|
||||
Under the hood, borgmatic accomplishes this by substituting globs for certain
|
||||
ephemeral data placeholders in your `archive_name_format`—and using the result
|
||||
to filter archives when running supported actions.
|
||||
|
||||
For instance, let's say that you have this in your configuration:
|
||||
|
||||
```yaml
|
||||
location:
|
||||
...
|
||||
archive_name_format: {hostname}-user-data-{now}
|
||||
```
|
||||
|
||||
borgmatic considers `{now}` an emphemeral data placeholder that will probably
|
||||
change per archive, while `{hostname}` won't. So it turns the example value
|
||||
into `{hostname}-user-data-*` and applies it to filter down the set of
|
||||
archives used for actions like `rlist`, `info`, `prune`, `check`, etc.
|
||||
|
||||
The end result is that when borgmatic runs the actions for a particular
|
||||
application-specific configuration file, it only operates on the archives
|
||||
created for that application. Of course, this doesn't apply to actions like
|
||||
`compact` that operate on an entire repository.
|
||||
|
||||
<span class="minilink minilink-addedin">Prior to 1.7.11</span> The way to
|
||||
limit the archives used for the `prune` action was a `prefix` option in the
|
||||
`retention` section for matching against the start of archive names. And the
|
||||
option for limiting the archives used for the `check` action was a separate
|
||||
`prefix` in the `consistency` section. Both of these options are deprecated in
|
||||
favor of the auto-matching behavior in newer versions of borgmatic.
|
||||
|
||||
|
||||
## Configuration includes
|
||||
|
||||
Once you have multiple different configuration files, you might want to share
|
||||
|
@ -272,7 +337,7 @@ Here's an example usage:
|
|||
```yaml
|
||||
constants:
|
||||
user: foo
|
||||
my_prefix: bar-
|
||||
archive_prefix: bar
|
||||
|
||||
location:
|
||||
source_directories:
|
||||
|
@ -281,20 +346,14 @@ location:
|
|||
...
|
||||
|
||||
storage:
|
||||
archive_name_format: '{my_prefix}{now}'
|
||||
|
||||
retention:
|
||||
prefix: {my_prefix}
|
||||
|
||||
consistency:
|
||||
prefix: {my_prefix}
|
||||
archive_name_format: '{archive_prefix}-{now}'
|
||||
```
|
||||
|
||||
In this example, when borgmatic runs, all instances of `{user}` get replaced
|
||||
with `foo` and all instances of `{my_prefix}` get replaced with `bar-`. (And
|
||||
in this particular example, `{now}` doesn't get replaced with anything, but
|
||||
gets passed directly to Borg.) After substitution, the logical result looks
|
||||
something like this:
|
||||
with `foo` and all instances of `{archive-prefix}` get replaced with `bar-`.
|
||||
(And in this particular example, `{now}` doesn't get replaced with anything,
|
||||
but gets passed directly to Borg.) After substitution, the logical result
|
||||
looks something like this:
|
||||
|
||||
```yaml
|
||||
location:
|
||||
|
@ -305,12 +364,6 @@ location:
|
|||
|
||||
storage:
|
||||
archive_name_format: 'bar-{now}'
|
||||
|
||||
retention:
|
||||
prefix: bar-
|
||||
|
||||
consistency:
|
||||
prefix: bar-
|
||||
```
|
||||
|
||||
An alternate to constants is passing in your values via [environment
|
||||
|
|
|
@ -90,7 +90,7 @@ installing borgmatic:
|
|||
* [Fedora unofficial](https://copr.fedorainfracloud.org/coprs/heffer/borgmatic/)
|
||||
* [Arch Linux](https://www.archlinux.org/packages/community/any/borgmatic/)
|
||||
* [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=borgmatic)
|
||||
* [OpenBSD](http://ports.su/sysutils/borgmatic)
|
||||
* [OpenBSD](https://openports.pl/path/sysutils/borgmatic)
|
||||
* [openSUSE](https://software.opensuse.org/package/borgmatic)
|
||||
* [macOS (via Homebrew)](https://formulae.brew.sh/formula/borgmatic)
|
||||
* [macOS (via MacPorts)](https://ports.macports.org/port/borgmatic/)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
# This script is for running all tests, including end-to-end tests, on a developer machine. It sets
|
||||
# up database containers to run tests against, runs the tests, and then tears down the containers.
|
||||
# This script is for running end-to-end tests on a developer machine. It sets up database containers
|
||||
# to run tests against, runs the tests, and then tears down the containers.
|
||||
#
|
||||
# Run this script from the root directory of the borgmatic source.
|
||||
#
|
||||
|
|
|
@ -8,7 +8,14 @@
|
|||
# For more information, see:
|
||||
# https://torsion.org/borgmatic/docs/how-to/develop-on-borgmatic/
|
||||
|
||||
set -ex
|
||||
set -e
|
||||
|
||||
if [ -z "$TEST_CONTAINER" ] ; then
|
||||
echo "This script is designed to work inside a test container and is not intended to"
|
||||
echo "be run manually. If you're trying to run borgmatic's end-to-end tests, execute"
|
||||
echo "scripts/run-end-to-end-dev-tests instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apk add --no-cache python3 py3-pip borgbackup postgresql-client mariadb-client mongodb-tools \
|
||||
py3-ruamel.yaml py3-ruamel.yaml.clib bash sqlite
|
||||
|
|
2
setup.py
2
setup.py
|
@ -1,6 +1,6 @@
|
|||
from setuptools import find_packages, setup
|
||||
|
||||
VERSION = '1.7.10'
|
||||
VERSION = '1.7.11.dev0'
|
||||
|
||||
|
||||
setup(
|
||||
|
|
|
@ -17,6 +17,8 @@ services:
|
|||
MONGO_INITDB_ROOT_PASSWORD: test
|
||||
tests:
|
||||
image: alpine:3.13
|
||||
environment:
|
||||
TEST_CONTAINER: true
|
||||
volumes:
|
||||
- "../..:/app:ro"
|
||||
tmpfs:
|
||||
|
@ -28,3 +30,4 @@ services:
|
|||
depends_on:
|
||||
- postgresql
|
||||
- mysql
|
||||
- mongodb
|
||||
|
|
|
@ -147,7 +147,7 @@ def test_log_outputs_kills_other_processes_when_one_errors():
|
|||
['sleep', '2'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
flexmock(module).should_receive('exit_code_indicates_error').with_args(
|
||||
other_process, None, 'borg'
|
||||
['sleep', '2'], None, 'borg'
|
||||
).and_return(False)
|
||||
flexmock(module).should_receive('output_buffer_for_process').with_args(process, ()).and_return(
|
||||
process.stdout
|
||||
|
|
|
@ -10,7 +10,7 @@ def test_run_transfer_does_not_raise():
|
|||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
module.run_transfer(
|
||||
repository='repo',
|
||||
repository={'path': 'repo'},
|
||||
storage={},
|
||||
local_borg_version=None,
|
||||
transfer_arguments=transfer_arguments,
|
||||
|
|
|
@ -189,150 +189,170 @@ def test_filter_checks_on_frequency_restains_check_with_unelapsed_frequency_and_
|
|||
|
||||
def test_make_check_flags_with_repository_check_returns_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository',))
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository',))
|
||||
|
||||
assert flags == ('--repository-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_returns_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('archives',))
|
||||
flags = module.make_check_flags('1.2.3', {}, ('archives',))
|
||||
|
||||
assert flags == ('--archives-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_data_check_returns_flag_and_implies_archives():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('data',))
|
||||
flags = module.make_check_flags('1.2.3', {}, ('data',))
|
||||
|
||||
assert flags == ('--archives-only', '--verify-data',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_extract_omits_extract_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('extract',))
|
||||
flags = module.make_check_flags('1.2.3', {}, ('extract',))
|
||||
|
||||
assert flags == ()
|
||||
|
||||
|
||||
def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository', 'data',))
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository', '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_prefix_returns_default_flags():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository', 'archives'), prefix='foo',)
|
||||
|
||||
assert flags == ('--match-archives', 'sh:foo*')
|
||||
|
||||
|
||||
def test_make_check_flags_with_all_checks_and_prefix_returns_default_flags():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags(
|
||||
'1.2.3', ('repository', 'archives'), prefix=module.DEFAULT_PREFIX
|
||||
'1.2.3', {}, ('repository', 'archives', 'extract'), prefix='foo',
|
||||
)
|
||||
|
||||
assert flags == ('--match-archives', f'sh:{module.DEFAULT_PREFIX}*')
|
||||
assert flags == ('--match-archives', 'sh:foo*')
|
||||
|
||||
|
||||
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(
|
||||
'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():
|
||||
def test_make_check_flags_with_all_checks_and_prefix_without_borg_features_returns_glob_archives_flags():
|
||||
flexmock(module.feature).should_receive('available').and_return(False)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags(
|
||||
'1.2.3', ('repository', 'archives', 'extract'), prefix=module.DEFAULT_PREFIX
|
||||
'1.2.3', {}, ('repository', 'archives', 'extract'), prefix='foo',
|
||||
)
|
||||
|
||||
assert flags == ('--glob-archives', f'{module.DEFAULT_PREFIX}*')
|
||||
assert flags == ('--glob-archives', 'foo*')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_last_includes_last_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('archives',), check_last=3)
|
||||
flags = module.make_check_flags('1.2.3', {}, ('archives',), check_last=3)
|
||||
|
||||
assert flags == ('--archives-only', '--last', '3')
|
||||
|
||||
|
||||
def test_make_check_flags_with_data_check_and_last_includes_last_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('data',), check_last=3)
|
||||
flags = module.make_check_flags('1.2.3', {}, ('data',), check_last=3)
|
||||
|
||||
assert flags == ('--archives-only', '--last', '3', '--verify-data')
|
||||
|
||||
|
||||
def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository',), check_last=3)
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository',), check_last=3)
|
||||
|
||||
assert flags == ('--repository-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_default_checks_and_last_includes_last_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository', 'archives'), check_last=3)
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository', 'archives'), check_last=3)
|
||||
|
||||
assert flags == ('--last', '3')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_prefix_includes_match_archives_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('archives',), prefix='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_data_check_and_prefix_includes_match_archives_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('data',), prefix='foo-')
|
||||
flags = module.make_check_flags('1.2.3', {}, ('data',), prefix='foo-')
|
||||
|
||||
assert flags == ('--archives-only', '--match-archives', 'sh:foo-*', '--verify-data')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_empty_prefix_omits_match_archives_flag():
|
||||
def test_make_check_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
'bar-{now}', '1.2.3' # noqa: FS003
|
||||
).and_return(('--match-archives', 'sh:bar-*'))
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('archives',), prefix='')
|
||||
flags = module.make_check_flags(
|
||||
'1.2.3', {'archive_name_format': 'bar-{now}'}, ('archives',), prefix='' # noqa: FS003
|
||||
)
|
||||
|
||||
assert flags == ('--archives-only',)
|
||||
assert flags == ('--archives-only', '--match-archives', 'sh:bar-*')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_none_prefix_omits_match_archives_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('archives',), prefix=None)
|
||||
flags = module.make_check_flags('1.2.3', {}, ('archives',), prefix=None)
|
||||
|
||||
assert flags == ('--archives-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_repository_check_and_prefix_omits_match_archives_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository',), prefix='foo-')
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository',), prefix='foo-')
|
||||
|
||||
assert flags == ('--repository-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_default_checks_and_prefix_includes_match_archives_flag():
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
flags = module.make_check_flags('1.2.3', ('repository', 'archives'), prefix='foo-')
|
||||
flags = module.make_check_flags('1.2.3', {}, ('repository', 'archives'), prefix='foo-')
|
||||
|
||||
assert flags == ('--match-archives', 'sh:foo-*')
|
||||
|
||||
|
@ -427,7 +447,7 @@ def test_check_archives_calls_borg_with_parameters(checks):
|
|||
'{"repository": {"id": "repo"}}'
|
||||
)
|
||||
flexmock(module).should_receive('make_check_flags').with_args(
|
||||
'1.2.3', checks, check_last, module.DEFAULT_PREFIX
|
||||
'1.2.3', {}, checks, check_last, prefix=None,
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
insert_execute_command_mock(('borg', 'check', 'repo'))
|
||||
|
@ -581,7 +601,7 @@ def test_check_archives_with_local_path_calls_borg_via_local_path():
|
|||
'{"repository": {"id": "repo"}}'
|
||||
)
|
||||
flexmock(module).should_receive('make_check_flags').with_args(
|
||||
'1.2.3', checks, check_last, module.DEFAULT_PREFIX
|
||||
'1.2.3', {}, checks, check_last, prefix=None,
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
insert_execute_command_mock(('borg1', 'check', 'repo'))
|
||||
|
@ -608,7 +628,7 @@ def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters(
|
|||
'{"repository": {"id": "repo"}}'
|
||||
)
|
||||
flexmock(module).should_receive('make_check_flags').with_args(
|
||||
'1.2.3', checks, check_last, module.DEFAULT_PREFIX
|
||||
'1.2.3', {}, checks, check_last, prefix=None,
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo'))
|
||||
|
@ -628,6 +648,7 @@ def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters(
|
|||
def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||
checks = ('repository',)
|
||||
check_last = flexmock()
|
||||
storage_config = {'lock_wait': 5}
|
||||
consistency_config = {'check_last': check_last}
|
||||
flexmock(module).should_receive('parse_checks')
|
||||
flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
|
||||
|
@ -635,7 +656,7 @@ def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
|||
'{"repository": {"id": "repo"}}'
|
||||
)
|
||||
flexmock(module).should_receive('make_check_flags').with_args(
|
||||
'1.2.3', checks, check_last, module.DEFAULT_PREFIX
|
||||
'1.2.3', storage_config, checks, check_last, None,
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo'))
|
||||
|
@ -645,7 +666,7 @@ def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
|||
module.check_archives(
|
||||
repository_path='repo',
|
||||
location_config={},
|
||||
storage_config={'lock_wait': 5},
|
||||
storage_config=storage_config,
|
||||
consistency_config=consistency_config,
|
||||
local_borg_version='1.2.3',
|
||||
)
|
||||
|
@ -662,7 +683,7 @@ def test_check_archives_with_retention_prefix():
|
|||
'{"repository": {"id": "repo"}}'
|
||||
)
|
||||
flexmock(module).should_receive('make_check_flags').with_args(
|
||||
'1.2.3', checks, check_last, prefix
|
||||
'1.2.3', {}, checks, check_last, prefix
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
insert_execute_command_mock(('borg', 'check', 'repo'))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import pytest
|
||||
from flexmock import flexmock
|
||||
|
||||
from borgmatic.borg import flags as module
|
||||
|
@ -78,3 +79,35 @@ def test_make_repository_archive_flags_with_borg_features_joins_repository_and_a
|
|||
assert module.make_repository_archive_flags(
|
||||
repository_path='repo', archive='archive', local_borg_version='1.2.3'
|
||||
) == ('repo::archive',)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'archive_name_format,feature_available,expected_result',
|
||||
(
|
||||
(None, True, ()),
|
||||
('', True, ()),
|
||||
(
|
||||
'{hostname}-docs-{now}', # noqa: FS003
|
||||
True,
|
||||
('--match-archives', 'sh:{hostname}-docs-*'), # noqa: FS003
|
||||
),
|
||||
('{utcnow}-docs-{user}', True, ('--match-archives', 'sh:*-docs-{user}')), # noqa: FS003
|
||||
('{fqdn}-{pid}', True, ('--match-archives', 'sh:{fqdn}-*')), # noqa: FS003
|
||||
(
|
||||
'stuff-{now:%Y-%m-%dT%H:%M:%S.%f}', # noqa: FS003
|
||||
True,
|
||||
('--match-archives', 'sh:stuff-*'),
|
||||
),
|
||||
('{hostname}-docs-{now}', False, ('--glob-archives', '{hostname}-docs-*')), # noqa: FS003
|
||||
('{utcnow}-docs-{user}', False, ('--glob-archives', '*-docs-{user}')), # noqa: FS003
|
||||
),
|
||||
)
|
||||
def test_make_match_archives_flags_makes_flags_with_globs(
|
||||
archive_name_format, feature_available, expected_result
|
||||
):
|
||||
flexmock(module.feature).should_receive('available').and_return(feature_available)
|
||||
|
||||
assert (
|
||||
module.make_match_archives_flags(archive_name_format, local_borg_version=flexmock())
|
||||
== expected_result
|
||||
)
|
||||
|
|
|
@ -12,6 +12,9 @@ def test_display_archives_info_calls_borg_with_parameters():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -34,6 +37,9 @@ def test_display_archives_info_with_log_info_calls_borg_with_info_parameter():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -56,6 +62,9 @@ def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_outpu
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
|
||||
flexmock(module.environment).should_receive('make_environment')
|
||||
|
@ -78,6 +87,9 @@ def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -101,6 +113,9 @@ def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_outp
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
|
||||
flexmock(module.environment).should_receive('make_environment')
|
||||
|
@ -123,6 +138,9 @@ def test_display_archives_info_with_json_calls_borg_with_json_parameter():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
|
||||
flexmock(module.environment).should_receive('make_environment')
|
||||
|
@ -147,6 +165,9 @@ def test_display_archives_info_with_archive_calls_borg_with_match_archives_param
|
|||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'match-archives', 'archive'
|
||||
).and_return(('--match-archives', 'archive'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -169,6 +190,9 @@ def test_display_archives_info_with_local_path_calls_borg_via_local_path():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -195,6 +219,9 @@ def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_para
|
|||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'remote-path', 'borg1'
|
||||
).and_return(('--remote-path', 'borg1'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -221,6 +248,9 @@ def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_paramete
|
|||
flexmock(module.flags).should_receive('make_flags').with_args('lock-wait', 5).and_return(
|
||||
('--lock-wait', '5')
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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'))
|
||||
storage_config = {'lock_wait': 5}
|
||||
|
@ -240,13 +270,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_match_archives_parameters():
|
||||
def test_display_archives_info_transforms_prefix_into_match_archives_parameters():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'match-archives', 'sh:foo*'
|
||||
).and_return(('--match-archives', 'sh:foo*'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
|
@ -265,12 +298,68 @@ def test_display_archives_info_with_prefix_calls_borg_with_match_archives_parame
|
|||
)
|
||||
|
||||
|
||||
def test_display_archives_info_prefers_prefix_over_archive_name_format():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'match-archives', 'sh:foo*'
|
||||
).and_return(('--match-archives', 'sh:foo*'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).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.environment).should_receive('make_environment')
|
||||
flexmock(module).should_receive('execute_command').with_args(
|
||||
('borg', 'info', '--match-archives', 'sh:foo*', '--repo', 'repo'),
|
||||
output_log_level=module.borgmatic.logger.ANSWER,
|
||||
borg_local_path='borg',
|
||||
extra_environment=None,
|
||||
)
|
||||
|
||||
module.display_archives_info(
|
||||
repository_path='repo',
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='2.3.4',
|
||||
info_arguments=flexmock(archive=None, json=False, prefix='foo'),
|
||||
)
|
||||
|
||||
|
||||
def test_display_archives_info_transforms_archive_name_format_into_match_archives_parameters():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
'bar-{now}', '2.3.4' # noqa: FS003
|
||||
).and_return(('--match-archives', 'sh:bar-*'))
|
||||
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.environment).should_receive('make_environment')
|
||||
flexmock(module).should_receive('execute_command').with_args(
|
||||
('borg', 'info', '--match-archives', 'sh:bar-*', '--repo', 'repo'),
|
||||
output_log_level=module.borgmatic.logger.ANSWER,
|
||||
borg_local_path='borg',
|
||||
extra_environment=None,
|
||||
)
|
||||
|
||||
module.display_archives_info(
|
||||
repository_path='repo',
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='2.3.4',
|
||||
info_arguments=flexmock(archive=None, json=False, prefix=None),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ('match_archives', 'sort_by', 'first', 'last'))
|
||||
def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flag_name = f"--{argument_name.replace('_', ' ')}"
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '2.3.4'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
|
||||
(flag_name, 'value')
|
||||
)
|
||||
|
|
|
@ -18,18 +18,17 @@ def insert_execute_command_mock(prune_command, output_log_level):
|
|||
).once()
|
||||
|
||||
|
||||
BASE_PRUNE_FLAGS = (('--keep-daily', '1'), ('--keep-weekly', '2'), ('--keep-monthly', '3'))
|
||||
BASE_PRUNE_FLAGS = ('--keep-daily', '1', '--keep-weekly', '2', '--keep-monthly', '3')
|
||||
|
||||
|
||||
def test_make_prune_flags_returns_flags_from_config_plus_default_prefix_glob():
|
||||
def test_make_prune_flags_returns_flags_from_config():
|
||||
retention_config = OrderedDict((('keep_daily', 1), ('keep_weekly', 2), ('keep_monthly', 3)))
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
|
||||
result = module.make_prune_flags({}, retention_config, local_borg_version='1.2.3')
|
||||
|
||||
assert tuple(result) == BASE_PRUNE_FLAGS + (
|
||||
('--match-archives', 'sh:{hostname}-*'), # noqa: FS003
|
||||
)
|
||||
assert result == BASE_PRUNE_FLAGS
|
||||
|
||||
|
||||
def test_make_prune_flags_accepts_prefix_with_placeholders():
|
||||
|
@ -37,15 +36,18 @@ def test_make_prune_flags_accepts_prefix_with_placeholders():
|
|||
(('keep_daily', 1), ('prefix', 'Documents_{hostname}-{now}')) # noqa: FS003
|
||||
)
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
|
||||
result = module.make_prune_flags({}, retention_config, local_borg_version='1.2.3')
|
||||
|
||||
expected = (
|
||||
('--keep-daily', '1'),
|
||||
('--match-archives', 'sh:Documents_{hostname}-{now}*'), # noqa: FS003
|
||||
'--keep-daily',
|
||||
'1',
|
||||
'--match-archives',
|
||||
'sh:Documents_{hostname}-{now}*', # noqa: FS003
|
||||
)
|
||||
|
||||
assert tuple(result) == expected
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives():
|
||||
|
@ -53,37 +55,38 @@ def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives()
|
|||
(('keep_daily', 1), ('prefix', 'Documents_{hostname}-{now}')) # noqa: FS003
|
||||
)
|
||||
flexmock(module.feature).should_receive('available').and_return(False)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
|
||||
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
|
||||
result = module.make_prune_flags({}, retention_config, local_borg_version='1.2.3')
|
||||
|
||||
expected = (
|
||||
('--keep-daily', '1'),
|
||||
('--glob-archives', 'Documents_{hostname}-{now}*'), # noqa: FS003
|
||||
'--keep-daily',
|
||||
'1',
|
||||
'--glob-archives',
|
||||
'Documents_{hostname}-{now}*', # noqa: FS003
|
||||
)
|
||||
|
||||
assert tuple(result) == expected
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_make_prune_flags_treats_empty_prefix_as_no_prefix():
|
||||
retention_config = OrderedDict((('keep_daily', 1), ('prefix', '')))
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
|
||||
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
|
||||
|
||||
expected = (('--keep-daily', '1'),)
|
||||
|
||||
assert tuple(result) == expected
|
||||
|
||||
|
||||
def test_make_prune_flags_treats_none_prefix_as_no_prefix():
|
||||
def test_make_prune_flags_without_prefix_uses_archive_name_format_instead():
|
||||
storage_config = {'archive_name_format': 'bar-{now}'} # noqa: FS003
|
||||
retention_config = OrderedDict((('keep_daily', 1), ('prefix', None)))
|
||||
flexmock(module.feature).should_receive('available').and_return(True)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
'bar-{now}', '1.2.3' # noqa: FS003
|
||||
).and_return(('--match-archives', 'sh:bar-*'))
|
||||
|
||||
result = module.make_prune_flags(retention_config, local_borg_version='1.2.3')
|
||||
result = module.make_prune_flags(storage_config, retention_config, local_borg_version='1.2.3')
|
||||
|
||||
expected = (('--keep-daily', '1'),)
|
||||
expected = (
|
||||
'--keep-daily',
|
||||
'1',
|
||||
'--match-archives',
|
||||
'sh:bar-*', # noqa: FS003
|
||||
)
|
||||
|
||||
assert tuple(result) == expected
|
||||
assert result == expected
|
||||
|
||||
|
||||
PRUNE_COMMAND = ('borg', 'prune', '--keep-daily', '1', '--keep-weekly', '2', '--keep-monthly', '3')
|
||||
|
|
|
@ -127,6 +127,9 @@ def test_resolve_archive_name_with_lock_wait_calls_borg_with_lock_wait_parameter
|
|||
def test_make_rlist_command_includes_log_info():
|
||||
insert_logging_mock(logging.INFO)
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -143,6 +146,9 @@ def test_make_rlist_command_includes_log_info():
|
|||
def test_make_rlist_command_includes_json_but_not_info():
|
||||
insert_logging_mock(logging.INFO)
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -159,6 +165,9 @@ def test_make_rlist_command_includes_json_but_not_info():
|
|||
def test_make_rlist_command_includes_log_debug():
|
||||
insert_logging_mock(logging.DEBUG)
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -175,6 +184,9 @@ def test_make_rlist_command_includes_log_debug():
|
|||
def test_make_rlist_command_includes_json_but_not_debug():
|
||||
insert_logging_mock(logging.DEBUG)
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -190,6 +202,9 @@ def test_make_rlist_command_includes_json_but_not_debug():
|
|||
|
||||
def test_make_rlist_command_includes_json():
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -207,6 +222,9 @@ def test_make_rlist_command_includes_lock_wait():
|
|||
flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(
|
||||
('--lock-wait', '5')
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -222,6 +240,9 @@ def test_make_rlist_command_includes_lock_wait():
|
|||
|
||||
def test_make_rlist_command_includes_local_path():
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -240,6 +261,9 @@ def test_make_rlist_command_includes_remote_path():
|
|||
flexmock(module.flags).should_receive('make_flags').and_return(
|
||||
('--remote-path', 'borg2')
|
||||
).and_return(()).and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -258,6 +282,9 @@ def test_make_rlist_command_transforms_prefix_into_match_archives():
|
|||
flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return(
|
||||
('--match-archives', 'sh:foo*')
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -271,8 +298,47 @@ def test_make_rlist_command_transforms_prefix_into_match_archives():
|
|||
assert command == ('borg', 'list', '--match-archives', 'sh:foo*', 'repo')
|
||||
|
||||
|
||||
def test_make_rlist_command_prefers_prefix_over_archive_name_format():
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return(
|
||||
('--match-archives', 'sh:foo*')
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').never()
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
command = module.make_rlist_command(
|
||||
repository_path='repo',
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='1.2.3',
|
||||
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix='foo'),
|
||||
)
|
||||
|
||||
assert command == ('borg', 'list', '--match-archives', 'sh:foo*', 'repo')
|
||||
|
||||
|
||||
def test_make_rlist_command_transforms_archive_name_format_into_match_archives():
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
'bar-{now}', '1.2.3' # noqa: FS003
|
||||
).and_return(('--match-archives', 'sh:bar-*'))
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
command = module.make_rlist_command(
|
||||
repository_path='repo',
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='1.2.3',
|
||||
rlist_arguments=flexmock(archive=None, paths=None, json=False, prefix=None),
|
||||
)
|
||||
|
||||
assert command == ('borg', 'list', '--match-archives', 'sh:bar-*', 'repo')
|
||||
|
||||
|
||||
def test_make_rlist_command_includes_short():
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--short',))
|
||||
flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
|
||||
|
||||
|
@ -301,6 +367,9 @@ def test_make_rlist_command_includes_short():
|
|||
)
|
||||
def test_make_rlist_command_includes_additional_flags(argument_name):
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
None, '1.2.3'
|
||||
).and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
|
||||
(f"--{argument_name.replace('_', '-')}", 'value')
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ def test_transfer_archives_calls_borg_with_flags():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -41,6 +42,7 @@ def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag():
|
|||
flexmock(module.flags).should_receive('make_flags').with_args('dry-run', True).and_return(
|
||||
('--dry-run',)
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -67,6 +69,7 @@ def test_transfer_archives_with_log_info_calls_borg_with_info_flag():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -93,6 +96,7 @@ def test_transfer_archives_with_log_debug_calls_borg_with_debug_flag():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -123,6 +127,7 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag():
|
|||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'match-archives', 'archive'
|
||||
).and_return(('--match-archives', 'archive'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -137,7 +142,7 @@ def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag():
|
|||
module.transfer_archives(
|
||||
dry_run=False,
|
||||
repository_path='repo',
|
||||
storage_config={},
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='2.3.4',
|
||||
transfer_arguments=flexmock(
|
||||
archive='archive', progress=None, match_archives=None, source_repository=None
|
||||
|
@ -152,6 +157,7 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl
|
|||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'match-archives', 'sh:foo*'
|
||||
).and_return(('--match-archives', 'sh:foo*'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -166,7 +172,7 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl
|
|||
module.transfer_archives(
|
||||
dry_run=False,
|
||||
repository_path='repo',
|
||||
storage_config={},
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='2.3.4',
|
||||
transfer_arguments=flexmock(
|
||||
archive=None, progress=None, match_archives='sh:foo*', source_repository=None
|
||||
|
@ -174,10 +180,40 @@ def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_fl
|
|||
)
|
||||
|
||||
|
||||
def test_transfer_archives_with_archive_name_format_calls_borg_with_match_archives_flag():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
|
||||
'bar-{now}', '2.3.4' # noqa: FS003
|
||||
).and_return(('--match-archives', 'sh:bar-*'))
|
||||
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.environment).should_receive('make_environment')
|
||||
flexmock(module).should_receive('execute_command').with_args(
|
||||
('borg', 'transfer', '--match-archives', 'sh:bar-*', '--repo', 'repo'),
|
||||
output_log_level=module.borgmatic.logger.ANSWER,
|
||||
output_file=None,
|
||||
borg_local_path='borg',
|
||||
extra_environment=None,
|
||||
)
|
||||
|
||||
module.transfer_archives(
|
||||
dry_run=False,
|
||||
repository_path='repo',
|
||||
storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
|
||||
local_borg_version='2.3.4',
|
||||
transfer_arguments=flexmock(
|
||||
archive=None, progress=None, match_archives=None, source_repository=None
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_transfer_archives_with_local_path_calls_borg_via_local_path():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -208,6 +244,7 @@ def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags():
|
|||
flexmock(module.flags).should_receive('make_flags').with_args(
|
||||
'remote-path', 'borg2'
|
||||
).and_return(('--remote-path', 'borg2'))
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -238,6 +275,7 @@ def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags():
|
|||
flexmock(module.flags).should_receive('make_flags').with_args('lock-wait', 5).and_return(
|
||||
('--lock-wait', '5')
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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'))
|
||||
storage_config = {'lock_wait': 5}
|
||||
|
@ -265,6 +303,7 @@ def test_transfer_archives_with_progress_calls_borg_with_progress_flag():
|
|||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
@ -293,6 +332,7 @@ def test_transfer_archives_passes_through_arguments_to_borg(argument_name):
|
|||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flag_name = f"--{argument_name.replace('_', ' ')}"
|
||||
flexmock(module.flags).should_receive('make_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
|
||||
(flag_name, 'value')
|
||||
)
|
||||
|
@ -327,6 +367,7 @@ def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_fla
|
|||
flexmock(module.flags).should_receive('make_flags').with_args('other-repo', 'other').and_return(
|
||||
('--other-repo', 'other')
|
||||
)
|
||||
flexmock(module.flags).should_receive('make_match_archives_flags').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.environment).should_receive('make_environment')
|
||||
|
|
|
@ -37,7 +37,7 @@ def test_validation_error_string_contains_errors():
|
|||
assert 'uh oh' in result
|
||||
|
||||
|
||||
def test_apply_locical_validation_raises_if_unknown_repository_in_check_repositories():
|
||||
def test_apply_logical_validation_raises_if_unknown_repository_in_check_repositories():
|
||||
flexmock(module).format_json_error = lambda error: error.message
|
||||
|
||||
with pytest.raises(module.Validation_error):
|
||||
|
@ -51,17 +51,33 @@ def test_apply_locical_validation_raises_if_unknown_repository_in_check_reposito
|
|||
)
|
||||
|
||||
|
||||
def test_apply_locical_validation_does_not_raise_if_known_repository_in_check_repositories():
|
||||
def test_apply_logical_validation_does_not_raise_if_known_repository_path_in_check_repositories():
|
||||
module.apply_logical_validation(
|
||||
'config.yaml',
|
||||
{
|
||||
'location': {'repositories': ['repo.borg', 'other.borg']},
|
||||
'location': {'repositories': [{'path': 'repo.borg'}, {'path': 'other.borg'}]},
|
||||
'retention': {'keep_secondly': 1000},
|
||||
'consistency': {'check_repositories': ['repo.borg']},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_apply_logical_validation_does_not_raise_if_known_repository_label_in_check_repositories():
|
||||
module.apply_logical_validation(
|
||||
'config.yaml',
|
||||
{
|
||||
'location': {
|
||||
'repositories': [
|
||||
{'path': 'repo.borg', 'label': 'my_repo'},
|
||||
{'path': 'other.borg', 'label': 'other_repo'},
|
||||
]
|
||||
},
|
||||
'retention': {'keep_secondly': 1000},
|
||||
'consistency': {'check_repositories': ['my_repo']},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_apply_logical_validation_does_not_raise_if_archive_name_format_and_prefix_present():
|
||||
module.apply_logical_validation(
|
||||
'config.yaml',
|
||||
|
|
Loading…
Reference in a new issue