Store included configuration files within each backup archive in support of the "config bootstrap" action (#736).
This commit is contained in:
parent
3c22a8ec16
commit
63198088c4
15 changed files with 401 additions and 204 deletions
2
NEWS
2
NEWS
|
@ -1,4 +1,6 @@
|
|||
1.8.7.dev0
|
||||
* #736: Store included configuration files within each backup archive in support of the "config
|
||||
bootstrap" action. Previously, only top-level configuration files were stored.
|
||||
* #810: SECURITY: Prevent shell injection attacks within the PostgreSQL hook, the MongoDB hook, the
|
||||
SQLite hook, the "borgmatic borg" action, and command hook variable/constant interpolation.
|
||||
|
||||
|
|
|
@ -13,14 +13,11 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
||||
'''
|
||||
Given:
|
||||
The bootstrap arguments, which include the repository and archive name, borgmatic source directory,
|
||||
destination directory, and whether to strip components.
|
||||
The global arguments, which include the dry run flag
|
||||
and the local borg version,
|
||||
Return:
|
||||
The config paths from the manifest.json file in the borgmatic source directory after extracting it from the
|
||||
repository.
|
||||
Given the bootstrap arguments as an argparse.Namespace (containing the repository and archive
|
||||
name, borgmatic source directory, destination directory, and whether to strip components), the
|
||||
global arguments as an argparse.Namespace (containing the dry run flag and the local borg
|
||||
version), return the config paths from the manifest.json file in the borgmatic source directory
|
||||
after extracting it from the repository.
|
||||
|
||||
Raise ValueError if the manifest JSON is missing, can't be decoded, or doesn't contain the
|
||||
expected configuration path data.
|
||||
|
@ -32,6 +29,7 @@ def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
os.path.join(borgmatic_source_directory, 'bootstrap', 'manifest.json')
|
||||
)
|
||||
config = {'ssh_command': bootstrap_arguments.ssh_command}
|
||||
|
||||
extract_process = borgmatic.borg.extract.extract_archive(
|
||||
global_arguments.dry_run,
|
||||
bootstrap_arguments.repository,
|
||||
|
@ -48,8 +46,8 @@ def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
global_arguments,
|
||||
extract_to_stdout=True,
|
||||
)
|
||||
|
||||
manifest_json = extract_process.stdout.read()
|
||||
|
||||
if not manifest_json:
|
||||
raise ValueError(
|
||||
'Cannot read configuration paths from archive due to missing bootstrap manifest'
|
||||
|
|
|
@ -47,6 +47,7 @@ def run_create(
|
|||
config_filename,
|
||||
repository,
|
||||
config,
|
||||
config_paths,
|
||||
hook_context,
|
||||
local_borg_version,
|
||||
create_arguments,
|
||||
|
@ -90,7 +91,9 @@ def run_create(
|
|||
)
|
||||
if config.get('store_config_files', True):
|
||||
create_borgmatic_manifest(
|
||||
config, global_arguments.used_config_paths, global_arguments.dry_run
|
||||
config,
|
||||
config_paths,
|
||||
global_arguments.dry_run,
|
||||
)
|
||||
stream_processes = [process for processes in active_dumps.values() for process in processes]
|
||||
|
||||
|
@ -98,6 +101,7 @@ def run_create(
|
|||
global_arguments.dry_run,
|
||||
repository['path'],
|
||||
config,
|
||||
config_paths,
|
||||
local_borg_version,
|
||||
global_arguments,
|
||||
local_path=local_path,
|
||||
|
|
|
@ -323,6 +323,7 @@ def create_archive(
|
|||
dry_run,
|
||||
repository_path,
|
||||
config,
|
||||
config_paths,
|
||||
local_borg_version,
|
||||
global_arguments,
|
||||
local_path='borg',
|
||||
|
@ -334,8 +335,9 @@ def create_archive(
|
|||
stream_processes=None,
|
||||
):
|
||||
'''
|
||||
Given vebosity/dry-run flags, a local or remote repository path, and a configuration dict,
|
||||
create a Borg archive and return Borg's JSON output (if any).
|
||||
Given vebosity/dry-run flags, a local or remote repository path, a configuration dict, a
|
||||
sequence of loaded configuration paths, the local Borg version, and global arguments as an
|
||||
argparse.Namespace instance, create a Borg archive and return Borg's JSON output (if any).
|
||||
|
||||
If a sequence of stream processes is given (instances of subprocess.Popen), then execute the
|
||||
create command while also triggering the given processes to produce output.
|
||||
|
@ -351,11 +353,7 @@ def create_archive(
|
|||
expand_directories(
|
||||
tuple(config.get('source_directories', ()))
|
||||
+ borgmatic_source_directories
|
||||
+ tuple(
|
||||
global_arguments.used_config_paths
|
||||
if config.get('store_config_files', True)
|
||||
else ()
|
||||
)
|
||||
+ tuple(config_paths if config.get('store_config_files', True) else ())
|
||||
)
|
||||
),
|
||||
additional_directory_devices=map_directories_to_devices(
|
||||
|
|
|
@ -58,11 +58,11 @@ def get_skip_actions(config, arguments):
|
|||
return skip_actions
|
||||
|
||||
|
||||
def run_configuration(config_filename, config, arguments):
|
||||
def run_configuration(config_filename, config, config_paths, arguments):
|
||||
'''
|
||||
Given a config filename, the corresponding parsed config dict, and command-line arguments as a
|
||||
dict from subparser name to a namespace of parsed arguments, execute the defined create, prune,
|
||||
compact, check, and/or other actions.
|
||||
Given a config filename, the corresponding parsed config dict, a sequence of loaded
|
||||
configuration paths, and command-line arguments as a dict from subparser name to a namespace of
|
||||
parsed arguments, execute the defined create, prune, compact, check, and/or other actions.
|
||||
|
||||
Yield a combination of:
|
||||
|
||||
|
@ -144,6 +144,7 @@ def run_configuration(config_filename, config, arguments):
|
|||
arguments=arguments,
|
||||
config_filename=config_filename,
|
||||
config=config,
|
||||
config_paths=config_paths,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
local_borg_version=local_borg_version,
|
||||
|
@ -264,6 +265,7 @@ def run_actions(
|
|||
arguments,
|
||||
config_filename,
|
||||
config,
|
||||
config_paths,
|
||||
local_path,
|
||||
remote_path,
|
||||
local_borg_version,
|
||||
|
@ -271,9 +273,9 @@ def run_actions(
|
|||
):
|
||||
'''
|
||||
Given parsed command-line arguments as an argparse.ArgumentParser instance, the configuration
|
||||
filename, several different configuration dicts, local and remote paths to Borg, a local Borg
|
||||
version string, and a repository name, run all actions from the command-line arguments on the
|
||||
given repository.
|
||||
filename, a configuration dict, a sequence of loaded configuration paths, local and remote paths
|
||||
to Borg, a local Borg version string, and a repository name, run all actions from the
|
||||
command-line arguments on the given repository.
|
||||
|
||||
Yield JSON output strings from executing any actions that produce JSON.
|
||||
|
||||
|
@ -328,6 +330,7 @@ def run_actions(
|
|||
config_filename,
|
||||
repository,
|
||||
config,
|
||||
config_paths,
|
||||
hook_context,
|
||||
local_borg_version,
|
||||
action_arguments,
|
||||
|
@ -502,13 +505,15 @@ def load_configurations(config_filenames, overrides=None, resolve_env=True):
|
|||
'''
|
||||
Given a sequence of configuration filenames, load and validate each configuration file. Return
|
||||
the results as a tuple of: dict of configuration filename to corresponding parsed configuration,
|
||||
and sequence of logging.LogRecord instances containing any parse errors.
|
||||
a sequence of paths for all loaded configuration files (including includes), and a sequence of
|
||||
logging.LogRecord instances containing any parse errors.
|
||||
|
||||
Log records are returned here instead of being logged directly because logging isn't yet
|
||||
initialized at this point!
|
||||
'''
|
||||
# Dict mapping from config filename to corresponding parsed config dict.
|
||||
configs = collections.OrderedDict()
|
||||
config_paths = set()
|
||||
logs = []
|
||||
|
||||
# Parse and load each configuration file.
|
||||
|
@ -525,9 +530,10 @@ def load_configurations(config_filenames, overrides=None, resolve_env=True):
|
|||
]
|
||||
)
|
||||
try:
|
||||
configs[config_filename], parse_logs = validate.parse_configuration(
|
||||
configs[config_filename], paths, parse_logs = validate.parse_configuration(
|
||||
config_filename, validate.schema_filename(), overrides, resolve_env
|
||||
)
|
||||
config_paths.update(paths)
|
||||
logs.extend(parse_logs)
|
||||
except PermissionError:
|
||||
logs.extend(
|
||||
|
@ -557,7 +563,7 @@ def load_configurations(config_filenames, overrides=None, resolve_env=True):
|
|||
]
|
||||
)
|
||||
|
||||
return (configs, logs)
|
||||
return (configs, sorted(config_paths), logs)
|
||||
|
||||
|
||||
def log_record(suppress_log=False, **kwargs):
|
||||
|
@ -724,12 +730,12 @@ def collect_highlander_action_summary_logs(configs, arguments, configuration_par
|
|||
return
|
||||
|
||||
|
||||
def collect_configuration_run_summary_logs(configs, arguments):
|
||||
def collect_configuration_run_summary_logs(configs, config_paths, arguments):
|
||||
'''
|
||||
Given a dict of configuration filename to corresponding parsed configuration and parsed
|
||||
command-line arguments as a dict from subparser name to a parsed namespace of arguments, run
|
||||
each configuration file and yield a series of logging.LogRecord instances containing summary
|
||||
information about each run.
|
||||
Given a dict of configuration filename to corresponding parsed configuration, a sequence of
|
||||
loaded configuration paths, and parsed command-line arguments as a dict from subparser name to a
|
||||
parsed namespace of arguments, run each configuration file and yield a series of
|
||||
logging.LogRecord instances containing summary information about each run.
|
||||
|
||||
As a side effect of running through these configuration files, output their JSON results, if
|
||||
any, to stdout.
|
||||
|
@ -774,7 +780,7 @@ def collect_configuration_run_summary_logs(configs, arguments):
|
|||
# Execute the actions corresponding to each configuration file.
|
||||
json_results = []
|
||||
for config_filename, config in configs.items():
|
||||
results = list(run_configuration(config_filename, config, arguments))
|
||||
results = list(run_configuration(config_filename, config, config_paths, arguments))
|
||||
error_logs = tuple(result for result in results if isinstance(result, logging.LogRecord))
|
||||
|
||||
if error_logs:
|
||||
|
@ -855,8 +861,7 @@ def main(extra_summary_logs=[]): # pragma: no cover
|
|||
sys.exit(0)
|
||||
|
||||
config_filenames = tuple(collect.collect_config_filenames(global_arguments.config_paths))
|
||||
global_arguments.used_config_paths = list(config_filenames)
|
||||
configs, parse_logs = load_configurations(
|
||||
configs, config_paths, parse_logs = load_configurations(
|
||||
config_filenames, global_arguments.overrides, global_arguments.resolve_env
|
||||
)
|
||||
configuration_parse_errors = (
|
||||
|
@ -893,7 +898,7 @@ def main(extra_summary_logs=[]): # pragma: no cover
|
|||
configs, arguments, configuration_parse_errors
|
||||
)
|
||||
)
|
||||
or list(collect_configuration_run_summary_logs(configs, arguments))
|
||||
or list(collect_configuration_run_summary_logs(configs, config_paths, arguments))
|
||||
)
|
||||
)
|
||||
summary_logs_max_level = max(log.levelno for log in summary_logs)
|
||||
|
|
|
@ -225,8 +225,7 @@ def merge_source_configuration_into_destination(destination_config, source_confi
|
|||
favoring values from the source when there are collisions.
|
||||
|
||||
The purpose of this is to upgrade configuration files from old versions of borgmatic by adding
|
||||
new
|
||||
configuration keys and comments.
|
||||
new configuration keys and comments.
|
||||
'''
|
||||
if not source_config:
|
||||
return destination_config
|
||||
|
|
|
@ -9,18 +9,18 @@ import ruamel.yaml
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def probe_and_include_file(filename, include_directories):
|
||||
def probe_and_include_file(filename, include_directories, config_paths):
|
||||
'''
|
||||
Given a filename to include and a list of include directories to search for matching files,
|
||||
probe for the file, load it, and return the loaded configuration as a data structure of nested
|
||||
dicts, lists, etc.
|
||||
Given a filename to include, a list of include directories to search for matching files, and a
|
||||
set of configuration paths, probe for the file, load it, and return the loaded configuration as
|
||||
a data structure of nested dicts, lists, etc. Add the filename to the given configuration paths.
|
||||
|
||||
Raise FileNotFoundError if the included file was not found.
|
||||
'''
|
||||
expanded_filename = os.path.expanduser(filename)
|
||||
|
||||
if os.path.isabs(expanded_filename):
|
||||
return load_configuration(expanded_filename)
|
||||
return load_configuration(expanded_filename, config_paths)
|
||||
|
||||
candidate_filenames = {
|
||||
os.path.join(directory, expanded_filename) for directory in include_directories
|
||||
|
@ -28,32 +28,33 @@ def probe_and_include_file(filename, include_directories):
|
|||
|
||||
for candidate_filename in candidate_filenames:
|
||||
if os.path.exists(candidate_filename):
|
||||
return load_configuration(candidate_filename)
|
||||
return load_configuration(candidate_filename, config_paths)
|
||||
|
||||
raise FileNotFoundError(
|
||||
f'Could not find include {filename} at {" or ".join(candidate_filenames)}'
|
||||
)
|
||||
|
||||
|
||||
def include_configuration(loader, filename_node, include_directory):
|
||||
def include_configuration(loader, filename_node, include_directory, config_paths):
|
||||
'''
|
||||
Given a ruamel.yaml.loader.Loader, a ruamel.yaml.nodes.ScalarNode containing the included
|
||||
filename (or a list containing multiple such filenames), and an include directory path to search
|
||||
for matching files, load the given YAML filenames (ignoring the given loader so we can use our
|
||||
own) and return their contents as data structure of nested dicts, lists, etc. If the given
|
||||
filename (or a list containing multiple such filenames), an include directory path to search for
|
||||
matching files, and a set of configuration paths, load the given YAML filenames (ignoring the
|
||||
given loader so we can use our own) and return their contents as data structure of nested dicts,
|
||||
lists, etc. Add the names of included files to the given configuration paths. If the given
|
||||
filename node's value is a scalar string, then the return value will be a single value. But if
|
||||
the given node value is a list, then the return value will be a list of values, one per loaded
|
||||
configuration file.
|
||||
|
||||
If a filename is relative, probe for it within 1. the current working directory and 2. the given
|
||||
include directory.
|
||||
If a filename is relative, probe for it within: 1. the current working directory and 2. the
|
||||
given include directory.
|
||||
|
||||
Raise FileNotFoundError if an included file was not found.
|
||||
'''
|
||||
include_directories = [os.getcwd(), os.path.abspath(include_directory)]
|
||||
|
||||
if isinstance(filename_node.value, str):
|
||||
return probe_and_include_file(filename_node.value, include_directories)
|
||||
return probe_and_include_file(filename_node.value, include_directories, config_paths)
|
||||
|
||||
if (
|
||||
isinstance(filename_node.value, list)
|
||||
|
@ -63,7 +64,7 @@ def include_configuration(loader, filename_node, include_directory):
|
|||
# Reversing the values ensures the correct ordering if these includes are subsequently
|
||||
# merged together.
|
||||
return [
|
||||
probe_and_include_file(node.value, include_directories)
|
||||
probe_and_include_file(node.value, include_directories, config_paths)
|
||||
for node in reversed(filename_node.value)
|
||||
]
|
||||
|
||||
|
@ -109,11 +110,17 @@ class Include_constructor(ruamel.yaml.SafeConstructor):
|
|||
separate YAML configuration files. Example syntax: `option: !include common.yaml`
|
||||
'''
|
||||
|
||||
def __init__(self, preserve_quotes=None, loader=None, include_directory=None):
|
||||
def __init__(
|
||||
self, preserve_quotes=None, loader=None, include_directory=None, config_paths=None
|
||||
):
|
||||
super(Include_constructor, self).__init__(preserve_quotes, loader)
|
||||
self.add_constructor(
|
||||
'!include',
|
||||
functools.partial(include_configuration, include_directory=include_directory),
|
||||
functools.partial(
|
||||
include_configuration,
|
||||
include_directory=include_directory,
|
||||
config_paths=config_paths,
|
||||
),
|
||||
)
|
||||
|
||||
# These are catch-all error handlers for tags that don't get applied and removed by
|
||||
|
@ -155,26 +162,33 @@ class Include_constructor(ruamel.yaml.SafeConstructor):
|
|||
node.value = deep_merge_nodes(node.value)
|
||||
|
||||
|
||||
def load_configuration(filename):
|
||||
def load_configuration(filename, config_paths=None):
|
||||
'''
|
||||
Load the given configuration file and return its contents as a data structure of nested dicts
|
||||
and lists.
|
||||
and lists. Add the filename to the given configuration paths set, and also add any included
|
||||
configuration filenames.
|
||||
|
||||
Raise ruamel.yaml.error.YAMLError if something goes wrong parsing the YAML, or RecursionError
|
||||
if there are too many recursive includes.
|
||||
'''
|
||||
if config_paths is None:
|
||||
config_paths = set()
|
||||
|
||||
# Use an embedded derived class for the include constructor so as to capture the filename
|
||||
# value. (functools.partial doesn't work for this use case because yaml.Constructor has to be
|
||||
# an actual class.)
|
||||
class Include_constructor_with_include_directory(Include_constructor):
|
||||
# Use an embedded derived class for the include constructor so as to capture the include
|
||||
# directory and configuration paths values. (functools.partial doesn't work for this use case
|
||||
# because yaml.Constructor has to be an actual class.)
|
||||
class Include_constructor_with_extras(Include_constructor):
|
||||
def __init__(self, preserve_quotes=None, loader=None):
|
||||
super(Include_constructor_with_include_directory, self).__init__(
|
||||
preserve_quotes, loader, include_directory=os.path.dirname(filename)
|
||||
super(Include_constructor_with_extras, self).__init__(
|
||||
preserve_quotes,
|
||||
loader,
|
||||
include_directory=os.path.dirname(filename),
|
||||
config_paths=config_paths,
|
||||
)
|
||||
|
||||
yaml = ruamel.yaml.YAML(typ='safe')
|
||||
yaml.Constructor = Include_constructor_with_include_directory
|
||||
yaml.Constructor = Include_constructor_with_extras
|
||||
config_paths.add(filename)
|
||||
|
||||
with open(filename) as file:
|
||||
return yaml.load(file.read())
|
||||
|
|
|
@ -97,14 +97,16 @@ def parse_configuration(config_filename, schema_filename, overrides=None, resolv
|
|||
'checks': ['repository', 'archives'],
|
||||
}
|
||||
|
||||
Also return a sequence of logging.LogRecord instances containing any warnings about the
|
||||
configuration.
|
||||
Also return a set of loaded configuration paths and a sequence of logging.LogRecord instances
|
||||
containing any warnings about the configuration.
|
||||
|
||||
Raise FileNotFoundError if the file does not exist, PermissionError if the user does not
|
||||
have permissions to read the file, or Validation_error if the config does not match the schema.
|
||||
'''
|
||||
config_paths = set()
|
||||
|
||||
try:
|
||||
config = load.load_configuration(config_filename)
|
||||
config = load.load_configuration(config_filename, config_paths)
|
||||
schema = load.load_configuration(schema_filename)
|
||||
except (ruamel.yaml.error.YAMLError, RecursionError) as error:
|
||||
raise Validation_error(config_filename, (str(error),))
|
||||
|
@ -130,7 +132,7 @@ def parse_configuration(config_filename, schema_filename, overrides=None, resolv
|
|||
|
||||
apply_logical_validation(config_filename, config)
|
||||
|
||||
return config, logs
|
||||
return config, config_paths, logs
|
||||
|
||||
|
||||
def normalize_repository_path(repository):
|
||||
|
|
|
@ -191,3 +191,8 @@ for bootstrapping.
|
|||
borgmatic configuration files, for instance if they contain sensitive
|
||||
information you don't want to store even inside your encrypted backups. If you
|
||||
do this though, the `config bootstrap` action will no longer work.
|
||||
|
||||
<span class="minilink minilink-addedin">New in version 1.8.7</span> Included
|
||||
configuration files are stored in each backup archive. This means that the
|
||||
`config bootstrap` action not only extracts the top-level configuration files
|
||||
but also the includes they depend upon.
|
||||
|
|
|
@ -12,7 +12,10 @@ def test_load_configuration_parses_contents():
|
|||
config_file = io.StringIO('key: value')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
assert module.load_configuration('config.yaml') == {'key': 'value'}
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'}
|
||||
assert config_paths == {'config.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_with_only_integer_value_does_not_raise():
|
||||
|
@ -20,7 +23,10 @@ def test_load_configuration_with_only_integer_value_does_not_raise():
|
|||
config_file = io.StringIO('33')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
assert module.load_configuration('config.yaml') == 33
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml', config_paths) == 33
|
||||
assert config_paths == {'config.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_inlines_include_relative_to_current_directory():
|
||||
|
@ -34,8 +40,10 @@ def test_load_configuration_inlines_include_relative_to_current_directory():
|
|||
config_file = io.StringIO('key: !include include.yaml')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'key': 'value'}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'}
|
||||
assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_inlines_include_relative_to_config_parent_directory():
|
||||
|
@ -56,8 +64,10 @@ def test_load_configuration_inlines_include_relative_to_config_parent_directory(
|
|||
config_file = io.StringIO('key: !include include.yaml')
|
||||
config_file.name = '/etc/config.yaml'
|
||||
builtins.should_receive('open').with_args('/etc/config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('/etc/config.yaml') == {'key': 'value'}
|
||||
assert module.load_configuration('/etc/config.yaml', config_paths) == {'key': 'value'}
|
||||
assert config_paths == {'/etc/config.yaml', '/etc/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_raises_if_relative_include_does_not_exist():
|
||||
|
@ -70,9 +80,10 @@ def test_load_configuration_raises_if_relative_include_does_not_exist():
|
|||
config_file = io.StringIO('key: !include include.yaml')
|
||||
config_file.name = '/etc/config.yaml'
|
||||
builtins.should_receive('open').with_args('/etc/config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
module.load_configuration('/etc/config.yaml')
|
||||
module.load_configuration('/etc/config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_inlines_absolute_include():
|
||||
|
@ -86,8 +97,10 @@ def test_load_configuration_inlines_absolute_include():
|
|||
config_file = io.StringIO('key: !include /root/include.yaml')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'key': 'value'}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {'key': 'value'}
|
||||
assert config_paths == {'config.yaml', '/root/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_raises_if_absolute_include_does_not_exist():
|
||||
|
@ -98,9 +111,10 @@ def test_load_configuration_raises_if_absolute_include_does_not_exist():
|
|||
config_file = io.StringIO('key: !include /root/include.yaml')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
assert module.load_configuration('config.yaml')
|
||||
assert module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_inlines_multiple_file_include_as_list():
|
||||
|
@ -117,8 +131,15 @@ def test_load_configuration_inlines_multiple_file_include_as_list():
|
|||
config_file = io.StringIO('key: !include [/root/include1.yaml, /root/include2.yaml]')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'key': ['value2', 'value1']}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {'key': ['value2', 'value1']}
|
||||
assert config_paths == {
|
||||
'config.yaml',
|
||||
'/root/include1.yaml',
|
||||
'/root/include2.yaml',
|
||||
'other.yaml',
|
||||
}
|
||||
|
||||
|
||||
def test_load_configuration_include_with_unsupported_filename_type_raises():
|
||||
|
@ -129,9 +150,10 @@ def test_load_configuration_include_with_unsupported_filename_type_raises():
|
|||
config_file = io.StringIO('key: !include {path: /root/include.yaml}')
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_merges_include():
|
||||
|
@ -155,8 +177,13 @@ def test_load_configuration_merges_include():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'foo': 'override', 'baz': 'quux'}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {
|
||||
'foo': 'override',
|
||||
'baz': 'quux',
|
||||
}
|
||||
assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_merges_multiple_file_include():
|
||||
|
@ -188,12 +215,14 @@ def test_load_configuration_merges_multiple_file_include():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {
|
||||
assert module.load_configuration('config.yaml', config_paths) == {
|
||||
'foo': 'override',
|
||||
'baz': 'second',
|
||||
'original': 'yes',
|
||||
}
|
||||
assert config_paths == {'config.yaml', '/tmp/include1.yaml', '/tmp/include2.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_with_retain_tag_merges_include_but_keeps_local_values():
|
||||
|
@ -226,11 +255,13 @@ def test_load_configuration_with_retain_tag_merges_include_but_keeps_local_value
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {
|
||||
assert module.load_configuration('config.yaml', config_paths) == {
|
||||
'stuff': {'foo': 'override'},
|
||||
'other': {'a': 'override', 'c': 'd'},
|
||||
}
|
||||
assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_with_retain_tag_but_without_merge_include_raises():
|
||||
|
@ -256,9 +287,10 @@ def test_load_configuration_with_retain_tag_but_without_merge_include_raises():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_with_retain_tag_on_scalar_raises():
|
||||
|
@ -284,9 +316,10 @@ def test_load_configuration_with_retain_tag_on_scalar_raises():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_with_omit_tag_merges_include_and_omits_requested_values():
|
||||
|
@ -315,8 +348,10 @@ def test_load_configuration_with_omit_tag_merges_include_and_omits_requested_val
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'stuff': ['a', 'c', 'x', 'y']}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {'stuff': ['a', 'c', 'x', 'y']}
|
||||
assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_with_omit_tag_on_unknown_value_merges_include_and_does_not_raise():
|
||||
|
@ -345,8 +380,12 @@ def test_load_configuration_with_omit_tag_on_unknown_value_merges_include_and_do
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = {'other.yaml'}
|
||||
|
||||
assert module.load_configuration('config.yaml') == {'stuff': ['a', 'b', 'c', 'x', 'y']}
|
||||
assert module.load_configuration('config.yaml', config_paths) == {
|
||||
'stuff': ['a', 'b', 'c', 'x', 'y']
|
||||
}
|
||||
assert config_paths == {'config.yaml', '/tmp/include.yaml', 'other.yaml'}
|
||||
|
||||
|
||||
def test_load_configuration_with_omit_tag_on_non_list_item_raises():
|
||||
|
@ -374,9 +413,10 @@ def test_load_configuration_with_omit_tag_on_non_list_item_raises():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_with_omit_tag_on_non_scalar_list_item_raises():
|
||||
|
@ -403,9 +443,10 @@ def test_load_configuration_with_omit_tag_on_non_scalar_list_item_raises():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_with_omit_tag_but_without_merge_raises():
|
||||
|
@ -433,9 +474,10 @@ def test_load_configuration_with_omit_tag_but_without_merge_raises():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
module.load_configuration('config.yaml')
|
||||
module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
def test_load_configuration_does_not_merge_include_list():
|
||||
|
@ -460,9 +502,10 @@ def test_load_configuration_does_not_merge_include_list():
|
|||
)
|
||||
config_file.name = 'config.yaml'
|
||||
builtins.should_receive('open').with_args('config.yaml').and_return(config_file)
|
||||
config_paths = set()
|
||||
|
||||
with pytest.raises(module.ruamel.yaml.error.YAMLError):
|
||||
assert module.load_configuration('config.yaml')
|
||||
assert module.load_configuration('config.yaml', config_paths)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -58,7 +58,7 @@ def test_parse_configuration_transforms_file_into_mapping():
|
|||
'''
|
||||
)
|
||||
|
||||
config, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
|
||||
assert config == {
|
||||
'source_directories': ['/home', '/etc'],
|
||||
|
@ -68,6 +68,7 @@ def test_parse_configuration_transforms_file_into_mapping():
|
|||
'keep_minutely': 60,
|
||||
'checks': [{'name': 'repository'}, {'name': 'archives'}],
|
||||
}
|
||||
assert config_paths == {'/tmp/config.yaml'}
|
||||
assert logs == []
|
||||
|
||||
|
||||
|
@ -84,12 +85,13 @@ def test_parse_configuration_passes_through_quoted_punctuation():
|
|||
'''
|
||||
)
|
||||
|
||||
config, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
|
||||
assert config == {
|
||||
'source_directories': [f'/home/{string.punctuation}'],
|
||||
'repositories': [{'path': 'test.borg'}],
|
||||
}
|
||||
assert config_paths == {'/tmp/config.yaml'}
|
||||
assert logs == []
|
||||
|
||||
|
||||
|
@ -141,7 +143,7 @@ def test_parse_configuration_inlines_include_inside_deprecated_section():
|
|||
include_file.name = 'include.yaml'
|
||||
builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file)
|
||||
|
||||
config, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
|
||||
assert config == {
|
||||
'source_directories': ['/home'],
|
||||
|
@ -149,6 +151,7 @@ def test_parse_configuration_inlines_include_inside_deprecated_section():
|
|||
'keep_daily': 7,
|
||||
'keep_hourly': 24,
|
||||
}
|
||||
assert config_paths == {'/tmp/include.yaml', '/tmp/config.yaml'}
|
||||
assert len(logs) == 1
|
||||
|
||||
|
||||
|
@ -175,7 +178,7 @@ def test_parse_configuration_merges_include():
|
|||
include_file.name = 'include.yaml'
|
||||
builtins.should_receive('open').with_args('/tmp/include.yaml').and_return(include_file)
|
||||
|
||||
config, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
|
||||
assert config == {
|
||||
'source_directories': ['/home'],
|
||||
|
@ -183,6 +186,7 @@ def test_parse_configuration_merges_include():
|
|||
'keep_daily': 1,
|
||||
'keep_hourly': 24,
|
||||
}
|
||||
assert config_paths == {'/tmp/include.yaml', '/tmp/config.yaml'}
|
||||
assert logs == []
|
||||
|
||||
|
||||
|
@ -194,6 +198,9 @@ def test_parse_configuration_raises_for_missing_config_file():
|
|||
def test_parse_configuration_raises_for_missing_schema_file():
|
||||
mock_config_and_schema('')
|
||||
builtins = flexmock(sys.modules['builtins'])
|
||||
builtins.should_receive('open').with_args('/tmp/config.yaml').and_return(
|
||||
io.StringIO('foo: bar')
|
||||
)
|
||||
builtins.should_receive('open').with_args('/tmp/schema.yaml').and_raise(FileNotFoundError)
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
|
@ -233,7 +240,7 @@ def test_parse_configuration_applies_overrides():
|
|||
'''
|
||||
)
|
||||
|
||||
config, logs = module.parse_configuration(
|
||||
config, config_paths, logs = module.parse_configuration(
|
||||
'/tmp/config.yaml', '/tmp/schema.yaml', overrides=['location.local_path=borg2']
|
||||
)
|
||||
|
||||
|
@ -242,6 +249,7 @@ def test_parse_configuration_applies_overrides():
|
|||
'repositories': [{'path': 'hostname.borg'}],
|
||||
'local_path': 'borg2',
|
||||
}
|
||||
assert config_paths == {'/tmp/config.yaml'}
|
||||
assert logs == []
|
||||
|
||||
|
||||
|
@ -260,11 +268,12 @@ def test_parse_configuration_applies_normalization_after_environment_variable_in
|
|||
)
|
||||
flexmock(os).should_receive('getenv').replace_with(lambda variable_name, default: default)
|
||||
|
||||
config, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml')
|
||||
|
||||
assert config == {
|
||||
'source_directories': ['/home'],
|
||||
'repositories': [{'path': 'ssh://user@hostname/./repo'}],
|
||||
'exclude_if_present': ['.nobackup'],
|
||||
}
|
||||
assert config_paths == {'/tmp/config.yaml'}
|
||||
assert logs
|
||||
|
|
|
@ -22,13 +22,14 @@ def test_run_create_executes_and_calls_hooks_for_configured_repository():
|
|||
json=False,
|
||||
list_files=flexmock(),
|
||||
)
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[])
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
list(
|
||||
module.run_create(
|
||||
config_filename='test.yaml',
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
hook_context={},
|
||||
local_borg_version=None,
|
||||
create_arguments=create_arguments,
|
||||
|
@ -57,13 +58,14 @@ def test_run_create_with_store_config_files_false_does_not_create_borgmatic_mani
|
|||
json=False,
|
||||
list_files=flexmock(),
|
||||
)
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[])
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
list(
|
||||
module.run_create(
|
||||
config_filename='test.yaml',
|
||||
repository={'path': 'repo'},
|
||||
config={'store_config_files': False},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
hook_context={},
|
||||
local_borg_version=None,
|
||||
create_arguments=create_arguments,
|
||||
|
@ -94,13 +96,14 @@ def test_run_create_runs_with_selected_repository():
|
|||
json=False,
|
||||
list_files=flexmock(),
|
||||
)
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[])
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
list(
|
||||
module.run_create(
|
||||
config_filename='test.yaml',
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
hook_context={},
|
||||
local_borg_version=None,
|
||||
create_arguments=create_arguments,
|
||||
|
@ -126,13 +129,14 @@ def test_run_create_bails_if_repository_does_not_match():
|
|||
json=False,
|
||||
list_files=flexmock(),
|
||||
)
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[])
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
list(
|
||||
module.run_create(
|
||||
config_filename='test.yaml',
|
||||
repository='repo',
|
||||
config={},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
hook_context={},
|
||||
local_borg_version=None,
|
||||
create_arguments=create_arguments,
|
||||
|
@ -167,13 +171,14 @@ def test_run_create_produces_json():
|
|||
json=True,
|
||||
list_files=flexmock(),
|
||||
)
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False, used_config_paths=[])
|
||||
global_arguments = flexmock(monitoring_verbosity=1, dry_run=False)
|
||||
|
||||
assert list(
|
||||
module.run_create(
|
||||
config_filename='test.yaml',
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
hook_context={},
|
||||
local_borg_version=None,
|
||||
create_arguments=create_arguments,
|
||||
|
|
|
@ -506,8 +506,9 @@ def test_create_archive_calls_borg_with_parameters():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -549,8 +550,9 @@ def test_create_archive_calls_borg_with_environment():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -594,23 +596,24 @@ def test_create_archive_with_patterns_calls_borg_with_patterns_including_convert
|
|||
'repositories': ['repo'],
|
||||
'patterns': ['pattern'],
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
def test_create_archive_with_sources_and_used_config_paths_calls_borg_with_sources_and_config_paths():
|
||||
def test_create_archive_with_sources_and_config_paths_calls_borg_with_sources_and_config_paths():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([])
|
||||
flexmock(module).should_receive('deduplicate_directories').and_return(
|
||||
('foo', 'bar', '/etc/borgmatic/config.yaml')
|
||||
('foo', 'bar', '/tmp/test.yaml')
|
||||
)
|
||||
flexmock(module).should_receive('map_directories_to_devices').and_return({})
|
||||
flexmock(module).should_receive('expand_directories').with_args([]).and_return(())
|
||||
flexmock(module).should_receive('expand_directories').with_args(
|
||||
('foo', 'bar', '/etc/borgmatic/config.yaml')
|
||||
).and_return(('foo', 'bar', '/etc/borgmatic/config.yaml'))
|
||||
('foo', 'bar', '/tmp/test.yaml')
|
||||
).and_return(('foo', 'bar', '/tmp/test.yaml'))
|
||||
flexmock(module).should_receive('expand_directories').with_args([]).and_return(())
|
||||
flexmock(module).should_receive('pattern_root_directories').and_return([])
|
||||
flexmock(module.os.path).should_receive('expanduser').and_raise(TypeError)
|
||||
|
@ -627,7 +630,7 @@ def test_create_archive_with_sources_and_used_config_paths_calls_borg_with_sourc
|
|||
environment = {'BORG_THINGY': 'YUP'}
|
||||
flexmock(module.environment).should_receive('make_environment').and_return(environment)
|
||||
flexmock(module).should_receive('execute_command').with_args(
|
||||
('borg', 'create') + REPO_ARCHIVE_WITH_PATHS + ('/etc/borgmatic/config.yaml',),
|
||||
('borg', 'create') + REPO_ARCHIVE_WITH_PATHS + ('/tmp/test.yaml',),
|
||||
output_log_level=logging.INFO,
|
||||
output_file=None,
|
||||
borg_local_path='borg',
|
||||
|
@ -642,12 +645,13 @@ def test_create_archive_with_sources_and_used_config_paths_calls_borg_with_sourc
|
|||
'source_directories': ['foo', 'bar'],
|
||||
'repositories': ['repo'],
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=['/etc/borgmatic/config.yaml']),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
def test_create_archive_with_sources_and_used_config_paths_with_store_config_files_false_calls_borg_with_sources_and_no_config_paths():
|
||||
def test_create_archive_with_sources_and_config_paths_with_store_config_files_false_calls_borg_with_sources_and_no_config_paths():
|
||||
flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
|
||||
flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
|
||||
flexmock(module).should_receive('collect_borgmatic_source_directories').and_return([])
|
||||
|
@ -689,8 +693,9 @@ def test_create_archive_with_sources_and_used_config_paths_with_store_config_fil
|
|||
'repositories': ['repo'],
|
||||
'store_config_files': False,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=['/etc/borgmatic/config.yaml']),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -734,8 +739,9 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': ['exclude'],
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -777,8 +783,9 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -818,8 +825,9 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
json=True,
|
||||
)
|
||||
|
||||
|
@ -862,8 +870,9 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -903,8 +912,9 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
json=True,
|
||||
)
|
||||
|
||||
|
@ -946,8 +956,9 @@ def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -991,8 +1002,9 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats_paramete
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stats=True,
|
||||
)
|
||||
|
||||
|
@ -1035,8 +1047,9 @@ def test_create_archive_with_checkpoint_interval_calls_borg_with_checkpoint_inte
|
|||
'exclude_patterns': None,
|
||||
'checkpoint_interval': 600,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1078,8 +1091,9 @@ def test_create_archive_with_checkpoint_volume_calls_borg_with_checkpoint_volume
|
|||
'exclude_patterns': None,
|
||||
'checkpoint_volume': 1024,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1121,8 +1135,9 @@ def test_create_archive_with_chunker_params_calls_borg_with_chunker_params_param
|
|||
'exclude_patterns': None,
|
||||
'chunker_params': '1,2,3,4',
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1164,8 +1179,9 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters(
|
|||
'exclude_patterns': None,
|
||||
'compression': 'rle',
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1213,8 +1229,9 @@ def test_create_archive_with_upload_rate_limit_calls_borg_with_upload_ratelimit_
|
|||
'exclude_patterns': None,
|
||||
'upload_rate_limit': 100,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1258,8 +1275,9 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory
|
|||
'working_directory': '/working/dir',
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1301,8 +1319,9 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par
|
|||
'one_file_system': True,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1350,8 +1369,9 @@ def test_create_archive_with_numeric_ids_calls_borg_with_numeric_ids_parameter(
|
|||
'numeric_ids': True,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1403,8 +1423,9 @@ def test_create_archive_with_read_special_calls_borg_with_read_special_parameter
|
|||
'read_special': True,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1458,8 +1479,9 @@ def test_create_archive_with_basic_option_calls_borg_with_corresponding_paramete
|
|||
option_name: option_value,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1512,8 +1534,9 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete
|
|||
'atime': option_value,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1566,8 +1589,9 @@ def test_create_archive_with_flags_option_calls_borg_with_corresponding_paramete
|
|||
'flags': option_value,
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1609,8 +1633,9 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters(
|
|||
'files_cache': 'ctime,size',
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1651,8 +1676,9 @@ def test_create_archive_with_local_path_calls_borg_via_local_path():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
local_path='borg1',
|
||||
)
|
||||
|
||||
|
@ -1694,8 +1720,9 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters(
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
remote_path='borg1',
|
||||
)
|
||||
|
||||
|
@ -1738,8 +1765,9 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters():
|
|||
'exclude_patterns': None,
|
||||
'umask': 740,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1780,8 +1808,9 @@ def test_create_archive_with_log_json_calls_borg_with_log_json_parameters():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=True, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=True),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1823,8 +1852,9 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
|||
'exclude_patterns': None,
|
||||
'lock_wait': 5,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -1865,8 +1895,9 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_answer_ou
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stats=True,
|
||||
)
|
||||
|
||||
|
@ -1908,8 +1939,9 @@ def test_create_archive_with_files_calls_borg_with_list_parameter_and_answer_out
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
list_files=True,
|
||||
)
|
||||
|
||||
|
@ -1952,8 +1984,9 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
progress=True,
|
||||
)
|
||||
|
||||
|
@ -1995,8 +2028,9 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
progress=True,
|
||||
)
|
||||
|
||||
|
@ -2057,8 +2091,9 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
progress=True,
|
||||
stream_processes=processes,
|
||||
)
|
||||
|
@ -2121,8 +2156,9 @@ def test_create_archive_with_stream_processes_ignores_read_special_false_and_log
|
|||
'exclude_patterns': None,
|
||||
'read_special': False,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stream_processes=processes,
|
||||
)
|
||||
|
||||
|
@ -2188,8 +2224,9 @@ def test_create_archive_with_stream_processes_adds_special_files_to_excludes():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stream_processes=processes,
|
||||
)
|
||||
|
||||
|
@ -2252,8 +2289,9 @@ def test_create_archive_with_stream_processes_and_read_special_does_not_add_spec
|
|||
'exclude_patterns': None,
|
||||
'read_special': True,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stream_processes=processes,
|
||||
)
|
||||
|
||||
|
@ -2293,8 +2331,9 @@ def test_create_archive_with_json_calls_borg_with_json_parameter():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
json=True,
|
||||
)
|
||||
|
||||
|
@ -2336,8 +2375,9 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_parameter()
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
json=True,
|
||||
stats=True,
|
||||
)
|
||||
|
@ -2383,8 +2423,9 @@ def test_create_archive_with_source_directories_glob_expands():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2426,8 +2467,9 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2468,8 +2510,9 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories():
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2511,8 +2554,9 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name():
|
|||
'exclude_patterns': None,
|
||||
'archive_name_format': 'ARCHIVE_NAME',
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2555,8 +2599,9 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders():
|
|||
'exclude_patterns': None,
|
||||
'archive_name_format': 'Documents_{hostname}-{now}', # noqa: FS003
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2599,8 +2644,9 @@ def test_create_archive_with_repository_accepts_borg_placeholders():
|
|||
'exclude_patterns': None,
|
||||
'archive_name_format': 'Documents_{hostname}-{now}', # noqa: FS003
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2642,8 +2688,9 @@ def test_create_archive_with_extra_borg_options_calls_borg_with_extra_options():
|
|||
'exclude_patterns': None,
|
||||
'extra_borg_options': {'create': '--extra --options'},
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
@ -2702,8 +2749,9 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes_and_read
|
|||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
stream_processes=processes,
|
||||
)
|
||||
|
||||
|
@ -2727,8 +2775,9 @@ def test_create_archive_with_non_existent_directory_and_source_directories_must_
|
|||
'exclude_patterns': None,
|
||||
'source_directories_must_exist': True,
|
||||
},
|
||||
config_paths=['/tmp/test.yaml'],
|
||||
local_borg_version='1.2.3',
|
||||
global_arguments=flexmock(log_json=False, used_config_paths=[]),
|
||||
global_arguments=flexmock(log_json=False),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ def test_run_configuration_runs_actions_for_each_repository():
|
|||
config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1)}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -51,7 +51,7 @@ def test_run_configuration_with_skip_actions_does_not_raise():
|
|||
config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}], 'skip_actions': ['compact']}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1)}
|
||||
|
||||
list(module.run_configuration('test.yaml', config, arguments))
|
||||
list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
|
||||
def test_run_configuration_with_invalid_borg_version_errors():
|
||||
|
@ -64,7 +64,7 @@ def test_run_configuration_with_invalid_borg_version_errors():
|
|||
config = {'repositories': ['foo']}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'prune': flexmock()}
|
||||
|
||||
list(module.run_configuration('test.yaml', config, arguments))
|
||||
list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
|
||||
def test_run_configuration_logs_monitor_start_error():
|
||||
|
@ -80,7 +80,7 @@ def test_run_configuration_logs_monitor_start_error():
|
|||
config = {'repositories': ['foo']}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -96,7 +96,7 @@ def test_run_configuration_bails_for_monitor_start_soft_failure():
|
|||
config = {'repositories': ['foo']}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == []
|
||||
|
||||
|
@ -113,7 +113,7 @@ def test_run_configuration_logs_actions_error():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False)}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -130,7 +130,7 @@ def test_run_configuration_bails_for_actions_soft_failure():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == []
|
||||
|
||||
|
@ -148,7 +148,7 @@ def test_run_configuration_logs_monitor_log_error():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -167,7 +167,7 @@ def test_run_configuration_bails_for_monitor_log_soft_failure():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == []
|
||||
|
||||
|
@ -185,7 +185,7 @@ def test_run_configuration_logs_monitor_finish_error():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -204,7 +204,7 @@ def test_run_configuration_bails_for_monitor_finish_soft_failure():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == []
|
||||
|
||||
|
@ -219,7 +219,7 @@ def test_run_configuration_does_not_call_monitoring_hooks_if_monitoring_hooks_ar
|
|||
|
||||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=-2, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == []
|
||||
|
||||
|
||||
|
@ -236,7 +236,7 @@ def test_run_configuration_logs_on_error_hook_error():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -253,7 +253,7 @@ def test_run_configuration_bails_for_on_error_hook_soft_failure():
|
|||
config = {'repositories': [{'path': 'foo'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
|
||||
assert results == expected_results
|
||||
|
||||
|
@ -268,7 +268,7 @@ def test_run_configuration_retries_soft_error():
|
|||
flexmock(module).should_receive('log_error_records').and_return([flexmock()]).once()
|
||||
config = {'repositories': [{'path': 'foo'}], 'retries': 1}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == []
|
||||
|
||||
|
||||
|
@ -292,7 +292,7 @@ def test_run_configuration_retries_hard_error():
|
|||
).and_return(error_logs)
|
||||
config = {'repositories': [{'path': 'foo'}], 'retries': 1}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == error_logs
|
||||
|
||||
|
||||
|
@ -311,7 +311,7 @@ def test_run_configuration_repos_ordered():
|
|||
).and_return(expected_results[1:]).ordered()
|
||||
config = {'repositories': [{'path': 'foo'}, {'path': 'bar'}]}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == expected_results
|
||||
|
||||
|
||||
|
@ -346,7 +346,7 @@ def test_run_configuration_retries_round_robin():
|
|||
'retries': 1,
|
||||
}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == foo_error_logs + bar_error_logs
|
||||
|
||||
|
||||
|
@ -379,7 +379,7 @@ def test_run_configuration_retries_one_passes():
|
|||
'retries': 1,
|
||||
}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == error_logs
|
||||
|
||||
|
||||
|
@ -423,7 +423,7 @@ def test_run_configuration_retry_wait():
|
|||
'retry_wait': 10,
|
||||
}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == error_logs
|
||||
|
||||
|
||||
|
@ -463,7 +463,7 @@ def test_run_configuration_retries_timeout_multiple_repos():
|
|||
'retry_wait': 10,
|
||||
}
|
||||
arguments = {'global': flexmock(monitoring_verbosity=1, dry_run=False), 'create': flexmock()}
|
||||
results = list(module.run_configuration('test.yaml', config, arguments))
|
||||
results = list(module.run_configuration('test.yaml', config, ['/tmp/test.yaml'], arguments))
|
||||
assert results == error_logs
|
||||
|
||||
|
||||
|
@ -478,6 +478,7 @@ def test_run_actions_runs_rcreate():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'rcreate': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -495,6 +496,7 @@ def test_run_actions_adds_log_file_to_hook_context():
|
|||
config_filename=object,
|
||||
repository={'path': 'repo'},
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
hook_context={'repository': 'repo', 'repositories': '', 'log_file': 'foo'},
|
||||
local_borg_version=object,
|
||||
create_arguments=object,
|
||||
|
@ -509,6 +511,7 @@ def test_run_actions_adds_log_file_to_hook_context():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'create': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -529,6 +532,7 @@ def test_run_actions_runs_transfer():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'transfer': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -549,6 +553,7 @@ def test_run_actions_runs_create():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'create': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -569,6 +574,7 @@ def test_run_actions_with_skip_actions_skips_create():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'create': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': [], 'skip_actions': ['create']},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -588,6 +594,7 @@ def test_run_actions_runs_prune():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'prune': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -607,6 +614,7 @@ def test_run_actions_with_skip_actions_skips_prune():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'prune': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': [], 'skip_actions': ['prune']},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -626,6 +634,7 @@ def test_run_actions_runs_compact():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'compact': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -645,6 +654,7 @@ def test_run_actions_with_skip_actions_skips_compact():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'compact': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': [], 'skip_actions': ['compact']},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -665,6 +675,7 @@ def test_run_actions_runs_check_when_repository_enabled_for_checks():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'check': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -685,6 +696,7 @@ def test_run_actions_skips_check_when_repository_not_enabled_for_checks():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'check': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -705,6 +717,7 @@ def test_run_actions_with_skip_actions_skips_check():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'check': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': [], 'skip_actions': ['check']},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -724,6 +737,7 @@ def test_run_actions_runs_extract():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'extract': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -743,6 +757,7 @@ def test_run_actions_runs_export_tar():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'export-tar': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -762,6 +777,7 @@ def test_run_actions_runs_mount():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'mount': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -781,6 +797,7 @@ def test_run_actions_runs_restore():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'restore': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -801,6 +818,7 @@ def test_run_actions_runs_rlist():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'rlist': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -822,6 +840,7 @@ def test_run_actions_runs_list():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'list': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -843,6 +862,7 @@ def test_run_actions_runs_rinfo():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'rinfo': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -864,6 +884,7 @@ def test_run_actions_runs_info():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'info': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -884,6 +905,7 @@ def test_run_actions_runs_break_lock():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'break-lock': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -903,6 +925,7 @@ def test_run_actions_runs_export_key():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'export': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -922,6 +945,7 @@ def test_run_actions_runs_borg():
|
|||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'borg': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -946,6 +970,7 @@ def test_run_actions_runs_multiple_actions_in_argument_order():
|
|||
},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
|
@ -960,30 +985,33 @@ def test_load_configurations_collects_parsed_configurations_and_logs():
|
|||
test_expected_logs = [flexmock(), flexmock()]
|
||||
other_expected_logs = [flexmock(), flexmock()]
|
||||
flexmock(module.validate).should_receive('parse_configuration').and_return(
|
||||
configuration, test_expected_logs
|
||||
).and_return(other_configuration, other_expected_logs)
|
||||
configuration, ['/tmp/test.yaml'], test_expected_logs
|
||||
).and_return(other_configuration, ['/tmp/other.yaml'], other_expected_logs)
|
||||
|
||||
configs, logs = tuple(module.load_configurations(('test.yaml', 'other.yaml')))
|
||||
configs, config_paths, logs = tuple(module.load_configurations(('test.yaml', 'other.yaml')))
|
||||
|
||||
assert configs == {'test.yaml': configuration, 'other.yaml': other_configuration}
|
||||
assert config_paths == ['/tmp/other.yaml', '/tmp/test.yaml']
|
||||
assert set(logs) >= set(test_expected_logs + other_expected_logs)
|
||||
|
||||
|
||||
def test_load_configurations_logs_warning_for_permission_error():
|
||||
flexmock(module.validate).should_receive('parse_configuration').and_raise(PermissionError)
|
||||
|
||||
configs, logs = tuple(module.load_configurations(('test.yaml',)))
|
||||
configs, config_paths, logs = tuple(module.load_configurations(('test.yaml',)))
|
||||
|
||||
assert configs == {}
|
||||
assert config_paths == []
|
||||
assert max(log.levelno for log in logs) == logging.WARNING
|
||||
|
||||
|
||||
def test_load_configurations_logs_critical_for_parse_error():
|
||||
flexmock(module.validate).should_receive('parse_configuration').and_raise(ValueError)
|
||||
|
||||
configs, logs = tuple(module.load_configurations(('test.yaml',)))
|
||||
configs, config_paths, logs = tuple(module.load_configurations(('test.yaml',)))
|
||||
|
||||
assert configs == {}
|
||||
assert config_paths == []
|
||||
assert max(log.levelno for log in logs) == logging.CRITICAL
|
||||
|
||||
|
||||
|
@ -1214,7 +1242,9 @@ def test_collect_configuration_run_summary_logs_info_for_success():
|
|||
arguments = {}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO}
|
||||
|
@ -1226,7 +1256,9 @@ def test_collect_configuration_run_summary_executes_hooks_for_create():
|
|||
arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO}
|
||||
|
@ -1239,7 +1271,9 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_extract():
|
|||
arguments = {'extract': flexmock(repository='repo')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO}
|
||||
|
@ -1254,7 +1288,9 @@ def test_collect_configuration_run_summary_logs_extract_with_repository_error():
|
|||
arguments = {'extract': flexmock(repository='repo')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert logs == expected_logs
|
||||
|
@ -1267,7 +1303,9 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_mount():
|
|||
arguments = {'mount': flexmock(repository='repo')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO}
|
||||
|
@ -1282,7 +1320,9 @@ def test_collect_configuration_run_summary_logs_mount_with_repository_error():
|
|||
arguments = {'mount': flexmock(repository='repo')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert logs == expected_logs
|
||||
|
@ -1293,7 +1333,9 @@ def test_collect_configuration_run_summary_logs_missing_configs_error():
|
|||
expected_logs = (flexmock(),)
|
||||
flexmock(module).should_receive('log_error_records').and_return(expected_logs)
|
||||
|
||||
logs = tuple(module.collect_configuration_run_summary_logs({}, arguments=arguments))
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({}, config_paths=[], arguments=arguments)
|
||||
)
|
||||
|
||||
assert logs == expected_logs
|
||||
|
||||
|
@ -1305,7 +1347,9 @@ def test_collect_configuration_run_summary_logs_pre_hook_error():
|
|||
arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert logs == expected_logs
|
||||
|
@ -1320,7 +1364,9 @@ def test_collect_configuration_run_summary_logs_post_hook_error():
|
|||
arguments = {'create': flexmock(), 'global': flexmock(monitoring_verbosity=1, dry_run=False)}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert expected_logs[0] in logs
|
||||
|
@ -1335,7 +1381,9 @@ def test_collect_configuration_run_summary_logs_for_list_with_archive_and_reposi
|
|||
arguments = {'list': flexmock(repository='repo', archive='test')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert logs == expected_logs
|
||||
|
@ -1347,7 +1395,9 @@ def test_collect_configuration_run_summary_logs_info_for_success_with_list():
|
|||
arguments = {'list': flexmock(repository='repo', archive=None)}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO}
|
||||
|
@ -1362,7 +1412,9 @@ def test_collect_configuration_run_summary_logs_run_configuration_error():
|
|||
arguments = {}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.CRITICAL}
|
||||
|
@ -1378,7 +1430,9 @@ def test_collect_configuration_run_summary_logs_run_umount_error():
|
|||
arguments = {'umount': flexmock(mount_point='/mnt')}
|
||||
|
||||
logs = tuple(
|
||||
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}}, config_paths=['/tmp/test.yaml'], arguments=arguments
|
||||
)
|
||||
)
|
||||
|
||||
assert {log.levelno for log in logs} == {logging.INFO, logging.CRITICAL}
|
||||
|
@ -1396,6 +1450,8 @@ def test_collect_configuration_run_summary_logs_outputs_merged_json_results():
|
|||
|
||||
tuple(
|
||||
module.collect_configuration_run_summary_logs(
|
||||
{'test.yaml': {}, 'test2.yaml': {}}, arguments=arguments
|
||||
{'test.yaml': {}, 'test2.yaml': {}},
|
||||
config_paths=['/tmp/test.yaml', '/tmp/test2.yaml'],
|
||||
arguments=arguments,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -6,27 +6,35 @@ from borgmatic.config import load as module
|
|||
|
||||
def test_probe_and_include_file_with_absolute_path_skips_probing():
|
||||
config = flexmock()
|
||||
flexmock(module).should_receive('load_configuration').with_args('/etc/include.yaml').and_return(
|
||||
config
|
||||
).once()
|
||||
config_paths = set()
|
||||
flexmock(module).should_receive('load_configuration').with_args(
|
||||
'/etc/include.yaml', config_paths
|
||||
).and_return(config).once()
|
||||
|
||||
assert module.probe_and_include_file('/etc/include.yaml', ['/etc', '/var']) == config
|
||||
assert (
|
||||
module.probe_and_include_file('/etc/include.yaml', ['/etc', '/var'], config_paths) == config
|
||||
)
|
||||
|
||||
|
||||
def test_probe_and_include_file_with_relative_path_probes_include_directories():
|
||||
config = flexmock()
|
||||
config = {'foo': 'bar'}
|
||||
config_paths = set()
|
||||
flexmock(module.os.path).should_receive('exists').with_args('/etc/include.yaml').and_return(
|
||||
False
|
||||
)
|
||||
flexmock(module.os.path).should_receive('exists').with_args('/var/include.yaml').and_return(
|
||||
True
|
||||
)
|
||||
flexmock(module).should_receive('load_configuration').with_args('/etc/include.yaml').never()
|
||||
flexmock(module).should_receive('load_configuration').with_args('/var/include.yaml').and_return(
|
||||
config
|
||||
).once()
|
||||
flexmock(module).should_receive('load_configuration').with_args(
|
||||
'/etc/include.yaml', config_paths
|
||||
).never()
|
||||
flexmock(module).should_receive('load_configuration').with_args(
|
||||
'/var/include.yaml', config_paths
|
||||
).and_return(config).once()
|
||||
|
||||
assert module.probe_and_include_file('include.yaml', ['/etc', '/var']) == config
|
||||
assert module.probe_and_include_file('include.yaml', ['/etc', '/var'], config_paths) == {
|
||||
'foo': 'bar',
|
||||
}
|
||||
|
||||
|
||||
def test_probe_and_include_file_with_relative_path_and_missing_files_raises():
|
||||
|
@ -34,4 +42,4 @@ def test_probe_and_include_file_with_relative_path_and_missing_files_raises():
|
|||
flexmock(module).should_receive('load_configuration').never()
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
module.probe_and_include_file('include.yaml', ['/etc', '/var'])
|
||||
module.probe_and_include_file('include.yaml', ['/etc', '/var'], config_paths=set())
|
||||
|
|
Loading…
Reference in a new issue