Prep work for eventual container-dumping hooks: Generalize internal database hook "API" (#685).
This commit is contained in:
parent
7313430178
commit
b96d1898f7
17 changed files with 693 additions and 654 deletions
|
@ -78,17 +78,17 @@ def run_create(
|
||||||
)
|
)
|
||||||
logger.info(f'{repository.get("label", repository["path"])}: Creating archive{dry_run_label}')
|
logger.info(f'{repository.get("label", repository["path"])}: Creating archive{dry_run_label}')
|
||||||
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
||||||
'remove_database_dumps',
|
'remove_data_source_dumps',
|
||||||
config,
|
config,
|
||||||
repository['path'],
|
repository['path'],
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
global_arguments.dry_run,
|
global_arguments.dry_run,
|
||||||
)
|
)
|
||||||
active_dumps = borgmatic.hooks.dispatch.call_hooks(
|
active_dumps = borgmatic.hooks.dispatch.call_hooks(
|
||||||
'dump_databases',
|
'dump_data_sources',
|
||||||
config,
|
config,
|
||||||
repository['path'],
|
repository['path'],
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
global_arguments.dry_run,
|
global_arguments.dry_run,
|
||||||
)
|
)
|
||||||
if config.get('store_config_files', True):
|
if config.get('store_config_files', True):
|
||||||
|
@ -115,10 +115,10 @@ def run_create(
|
||||||
yield json.loads(json_output)
|
yield json.loads(json_output)
|
||||||
|
|
||||||
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
||||||
'remove_database_dumps',
|
'remove_data_source_dumps',
|
||||||
config,
|
config,
|
||||||
config_filename,
|
config_filename,
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
global_arguments.dry_run,
|
global_arguments.dry_run,
|
||||||
)
|
)
|
||||||
borgmatic.hooks.command.execute_hook(
|
borgmatic.hooks.command.execute_hook(
|
||||||
|
|
|
@ -17,27 +17,31 @@ logger = logging.getLogger(__name__)
|
||||||
UNSPECIFIED_HOOK = object()
|
UNSPECIFIED_HOOK = object()
|
||||||
|
|
||||||
|
|
||||||
def get_configured_database(
|
def get_configured_data_source(
|
||||||
config, archive_database_names, hook_name, database_name, configuration_database_name=None
|
config,
|
||||||
|
archive_data_source_names,
|
||||||
|
hook_name,
|
||||||
|
data_source_name,
|
||||||
|
configuration_data_source_name=None,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Find the first database with the given hook name and database name in the configuration dict and
|
Find the first data source with the given hook name and data source name in the configuration
|
||||||
the given archive database names dict (from hook name to database names contained in a
|
dict and the given archive data source names dict (from hook name to data source names contained
|
||||||
particular backup archive). If UNSPECIFIED_HOOK is given as the hook name, search all database
|
in a particular backup archive). If UNSPECIFIED_HOOK is given as the hook name, search all data
|
||||||
hooks for the named database. If a configuration database name is given, use that instead of the
|
source hooks for the named data source. If a configuration data source name is given, use that
|
||||||
database name to lookup the database in the given hooks configuration.
|
instead of the data source name to lookup the data source in the given hooks configuration.
|
||||||
|
|
||||||
Return the found database as a tuple of (found hook name, database configuration dict) or (None,
|
Return the found data source as a tuple of (found hook name, data source configuration dict) or
|
||||||
None) if not found.
|
(None, None) if not found.
|
||||||
'''
|
'''
|
||||||
if not configuration_database_name:
|
if not configuration_data_source_name:
|
||||||
configuration_database_name = database_name
|
configuration_data_source_name = data_source_name
|
||||||
|
|
||||||
if hook_name == UNSPECIFIED_HOOK:
|
if hook_name == UNSPECIFIED_HOOK:
|
||||||
hooks_to_search = {
|
hooks_to_search = {
|
||||||
hook_name: value
|
hook_name: value
|
||||||
for (hook_name, value) in config.items()
|
for (hook_name, value) in config.items()
|
||||||
if hook_name in borgmatic.hooks.dump.DATABASE_HOOK_NAMES
|
if hook_name in borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
@ -47,24 +51,17 @@ def get_configured_database(
|
||||||
|
|
||||||
return next(
|
return next(
|
||||||
(
|
(
|
||||||
(name, hook_database)
|
(name, hook_data_source)
|
||||||
for (name, hook) in hooks_to_search.items()
|
for (name, hook) in hooks_to_search.items()
|
||||||
for hook_database in hook
|
for hook_data_source in hook
|
||||||
if hook_database['name'] == configuration_database_name
|
if hook_data_source['name'] == configuration_data_source_name
|
||||||
and database_name in archive_database_names.get(name, [])
|
and data_source_name in archive_data_source_names.get(name, [])
|
||||||
),
|
),
|
||||||
(None, None),
|
(None, None),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_configured_hook_name_and_database(hooks, database_name):
|
def restore_single_data_source(
|
||||||
'''
|
|
||||||
Find the hook name and first database dict with the given database name in the configured hooks
|
|
||||||
dict. This searches across all database hooks.
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
def restore_single_database(
|
|
||||||
repository,
|
repository,
|
||||||
config,
|
config,
|
||||||
local_borg_version,
|
local_borg_version,
|
||||||
|
@ -73,27 +70,27 @@ def restore_single_database(
|
||||||
remote_path,
|
remote_path,
|
||||||
archive_name,
|
archive_name,
|
||||||
hook_name,
|
hook_name,
|
||||||
database,
|
data_source,
|
||||||
connection_params,
|
connection_params,
|
||||||
): # pragma: no cover
|
): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Given (among other things) an archive name, a database hook name, the hostname, port,
|
Given (among other things) an archive name, a data source hook name, the hostname, port,
|
||||||
username/password as connection params, and a configured database configuration dict, restore
|
username/password as connection params, and a configured data source configuration dict, restore
|
||||||
that database from the archive.
|
that data source from the archive.
|
||||||
'''
|
'''
|
||||||
logger.info(
|
logger.info(
|
||||||
f'{repository.get("label", repository["path"])}: Restoring database {database["name"]}'
|
f'{repository.get("label", repository["path"])}: Restoring data source {data_source["name"]}'
|
||||||
)
|
)
|
||||||
|
|
||||||
dump_pattern = borgmatic.hooks.dispatch.call_hooks(
|
dump_pattern = borgmatic.hooks.dispatch.call_hooks(
|
||||||
'make_database_dump_pattern',
|
'make_data_source_dump_pattern',
|
||||||
config,
|
config,
|
||||||
repository['path'],
|
repository['path'],
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
database['name'],
|
data_source['name'],
|
||||||
)[hook_name]
|
)[hook_name]
|
||||||
|
|
||||||
# Kick off a single database extract to stdout.
|
# Kick off a single data source extract to stdout.
|
||||||
extract_process = borgmatic.borg.extract.extract_archive(
|
extract_process = borgmatic.borg.extract.extract_archive(
|
||||||
dry_run=global_arguments.dry_run,
|
dry_run=global_arguments.dry_run,
|
||||||
repository=repository['path'],
|
repository=repository['path'],
|
||||||
|
@ -107,23 +104,23 @@ def restore_single_database(
|
||||||
destination_path='/',
|
destination_path='/',
|
||||||
# A directory format dump isn't a single file, and therefore can't extract
|
# A directory format dump isn't a single file, and therefore can't extract
|
||||||
# to stdout. In this case, the extract_process return value is None.
|
# to stdout. In this case, the extract_process return value is None.
|
||||||
extract_to_stdout=bool(database.get('format') != 'directory'),
|
extract_to_stdout=bool(data_source.get('format') != 'directory'),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Run a single database restore, consuming the extract stdout (if any).
|
# Run a single data source restore, consuming the extract stdout (if any).
|
||||||
borgmatic.hooks.dispatch.call_hooks(
|
borgmatic.hooks.dispatch.call_hooks(
|
||||||
function_name='restore_database_dump',
|
function_name='restore_data_source_dump',
|
||||||
config=config,
|
config=config,
|
||||||
log_prefix=repository['path'],
|
log_prefix=repository['path'],
|
||||||
hook_names=[hook_name],
|
hook_names=[hook_name],
|
||||||
database=database,
|
data_source=data_source,
|
||||||
dry_run=global_arguments.dry_run,
|
dry_run=global_arguments.dry_run,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params=connection_params,
|
connection_params=connection_params,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def collect_archive_database_names(
|
def collect_archive_data_source_names(
|
||||||
repository,
|
repository,
|
||||||
archive,
|
archive,
|
||||||
config,
|
config,
|
||||||
|
@ -135,60 +132,62 @@ def collect_archive_database_names(
|
||||||
'''
|
'''
|
||||||
Given a local or remote repository path, a resolved archive name, a configuration dict, the
|
Given a local or remote repository path, a resolved archive name, a configuration dict, the
|
||||||
local Borg version, global_arguments an argparse.Namespace, and local and remote Borg paths,
|
local Borg version, global_arguments an argparse.Namespace, and local and remote Borg paths,
|
||||||
query the archive for the names of databases it contains and return them as a dict from hook
|
query the archive for the names of data sources it contains as dumps and return them as a dict
|
||||||
name to a sequence of database names.
|
from hook name to a sequence of data source names.
|
||||||
'''
|
'''
|
||||||
borgmatic_source_directory = os.path.expanduser(
|
borgmatic_source_directory = os.path.expanduser(
|
||||||
config.get(
|
config.get(
|
||||||
'borgmatic_source_directory', borgmatic.borg.state.DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
'borgmatic_source_directory', borgmatic.borg.state.DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||||
)
|
)
|
||||||
).lstrip('/')
|
).lstrip('/')
|
||||||
parent_dump_path = os.path.expanduser(
|
|
||||||
borgmatic.hooks.dump.make_database_dump_path(borgmatic_source_directory, '*_databases/*/*')
|
|
||||||
)
|
|
||||||
dump_paths = borgmatic.borg.list.capture_archive_listing(
|
dump_paths = borgmatic.borg.list.capture_archive_listing(
|
||||||
repository,
|
repository,
|
||||||
archive,
|
archive,
|
||||||
config,
|
config,
|
||||||
local_borg_version,
|
local_borg_version,
|
||||||
global_arguments,
|
global_arguments,
|
||||||
list_path=parent_dump_path,
|
list_paths=[
|
||||||
|
os.path.expanduser(
|
||||||
|
borgmatic.hooks.dump.make_data_source_dump_path(borgmatic_source_directory, pattern)
|
||||||
|
)
|
||||||
|
for pattern in ('*_databases/*/*',)
|
||||||
|
],
|
||||||
local_path=local_path,
|
local_path=local_path,
|
||||||
remote_path=remote_path,
|
remote_path=remote_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Determine the database names corresponding to the dumps found in the archive and
|
# Determine the data source names corresponding to the dumps found in the archive and
|
||||||
# add them to restore_names.
|
# add them to restore_names.
|
||||||
archive_database_names = {}
|
archive_data_source_names = {}
|
||||||
|
|
||||||
for dump_path in dump_paths:
|
for dump_path in dump_paths:
|
||||||
try:
|
try:
|
||||||
(hook_name, _, database_name) = dump_path.split(
|
(hook_name, _, data_source_name) = dump_path.split(
|
||||||
borgmatic_source_directory + os.path.sep, 1
|
borgmatic_source_directory + os.path.sep, 1
|
||||||
)[1].split(os.path.sep)[0:3]
|
)[1].split(os.path.sep)[0:3]
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f'{repository}: Ignoring invalid database dump path "{dump_path}" in archive {archive}'
|
f'{repository}: Ignoring invalid data source dump path "{dump_path}" in archive {archive}'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if database_name not in archive_database_names.get(hook_name, []):
|
if data_source_name not in archive_data_source_names.get(hook_name, []):
|
||||||
archive_database_names.setdefault(hook_name, []).extend([database_name])
|
archive_data_source_names.setdefault(hook_name, []).extend([data_source_name])
|
||||||
|
|
||||||
return archive_database_names
|
return archive_data_source_names
|
||||||
|
|
||||||
|
|
||||||
def find_databases_to_restore(requested_database_names, archive_database_names):
|
def find_data_sources_to_restore(requested_data_source_names, archive_data_source_names):
|
||||||
'''
|
'''
|
||||||
Given a sequence of requested database names to restore and a dict of hook name to the names of
|
Given a sequence of requested data source names to restore and a dict of hook name to the names
|
||||||
databases found in an archive, return an expanded sequence of database names to restore,
|
of data sources found in an archive, return an expanded sequence of data source names to
|
||||||
replacing "all" with actual database names as appropriate.
|
restore, replacing "all" with actual data source names as appropriate.
|
||||||
|
|
||||||
Raise ValueError if any of the requested database names cannot be found in the archive.
|
Raise ValueError if any of the requested data source names cannot be found in the archive.
|
||||||
'''
|
'''
|
||||||
# A map from database hook name to the database names to restore for that hook.
|
# A map from data source hook name to the data source names to restore for that hook.
|
||||||
restore_names = (
|
restore_names = (
|
||||||
{UNSPECIFIED_HOOK: requested_database_names}
|
{UNSPECIFIED_HOOK: requested_data_source_names}
|
||||||
if requested_database_names
|
if requested_data_source_names
|
||||||
else {UNSPECIFIED_HOOK: ['all']}
|
else {UNSPECIFIED_HOOK: ['all']}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -197,56 +196,59 @@ def find_databases_to_restore(requested_database_names, archive_database_names):
|
||||||
if 'all' in restore_names[UNSPECIFIED_HOOK]:
|
if 'all' in restore_names[UNSPECIFIED_HOOK]:
|
||||||
restore_names[UNSPECIFIED_HOOK].remove('all')
|
restore_names[UNSPECIFIED_HOOK].remove('all')
|
||||||
|
|
||||||
for hook_name, database_names in archive_database_names.items():
|
for hook_name, data_source_names in archive_data_source_names.items():
|
||||||
restore_names.setdefault(hook_name, []).extend(database_names)
|
restore_names.setdefault(hook_name, []).extend(data_source_names)
|
||||||
|
|
||||||
# If a database is to be restored as part of "all", then remove it from restore names so
|
# If a data source is to be restored as part of "all", then remove it from restore names
|
||||||
# it doesn't get restored twice.
|
# so it doesn't get restored twice.
|
||||||
for database_name in database_names:
|
for data_source_name in data_source_names:
|
||||||
if database_name in restore_names[UNSPECIFIED_HOOK]:
|
if data_source_name in restore_names[UNSPECIFIED_HOOK]:
|
||||||
restore_names[UNSPECIFIED_HOOK].remove(database_name)
|
restore_names[UNSPECIFIED_HOOK].remove(data_source_name)
|
||||||
|
|
||||||
if not restore_names[UNSPECIFIED_HOOK]:
|
if not restore_names[UNSPECIFIED_HOOK]:
|
||||||
restore_names.pop(UNSPECIFIED_HOOK)
|
restore_names.pop(UNSPECIFIED_HOOK)
|
||||||
|
|
||||||
combined_restore_names = set(
|
combined_restore_names = set(
|
||||||
name for database_names in restore_names.values() for name in database_names
|
name for data_source_names in restore_names.values() for name in data_source_names
|
||||||
)
|
)
|
||||||
combined_archive_database_names = set(
|
combined_archive_data_source_names = set(
|
||||||
name for database_names in archive_database_names.values() for name in database_names
|
name
|
||||||
|
for data_source_names in archive_data_source_names.values()
|
||||||
|
for name in data_source_names
|
||||||
)
|
)
|
||||||
|
|
||||||
missing_names = sorted(set(combined_restore_names) - combined_archive_database_names)
|
missing_names = sorted(set(combined_restore_names) - combined_archive_data_source_names)
|
||||||
if missing_names:
|
if missing_names:
|
||||||
joined_names = ', '.join(f'"{name}"' for name in missing_names)
|
joined_names = ', '.join(f'"{name}"' for name in missing_names)
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Cannot restore database{'s' if len(missing_names) > 1 else ''} {joined_names} missing from archive"
|
f"Cannot restore data source{'s' if len(missing_names) > 1 else ''} {joined_names} missing from archive"
|
||||||
)
|
)
|
||||||
|
|
||||||
return restore_names
|
return restore_names
|
||||||
|
|
||||||
|
|
||||||
def ensure_databases_found(restore_names, remaining_restore_names, found_names):
|
def ensure_data_sources_found(restore_names, remaining_restore_names, found_names):
|
||||||
'''
|
'''
|
||||||
Given a dict from hook name to database names to restore, a dict from hook name to remaining
|
Given a dict from hook name to data source names to restore, a dict from hook name to remaining
|
||||||
database names to restore, and a sequence of found (actually restored) database names, raise
|
data source names to restore, and a sequence of found (actually restored) data source names,
|
||||||
ValueError if requested databases to restore were missing from the archive and/or configuration.
|
raise ValueError if requested data source to restore were missing from the archive and/or
|
||||||
|
configuration.
|
||||||
'''
|
'''
|
||||||
combined_restore_names = set(
|
combined_restore_names = set(
|
||||||
name
|
name
|
||||||
for database_names in tuple(restore_names.values())
|
for data_source_names in tuple(restore_names.values())
|
||||||
+ tuple(remaining_restore_names.values())
|
+ tuple(remaining_restore_names.values())
|
||||||
for name in database_names
|
for name in data_source_names
|
||||||
)
|
)
|
||||||
|
|
||||||
if not combined_restore_names and not found_names:
|
if not combined_restore_names and not found_names:
|
||||||
raise ValueError('No databases were found to restore')
|
raise ValueError('No data sources were found to restore')
|
||||||
|
|
||||||
missing_names = sorted(set(combined_restore_names) - set(found_names))
|
missing_names = sorted(set(combined_restore_names) - set(found_names))
|
||||||
if missing_names:
|
if missing_names:
|
||||||
joined_names = ', '.join(f'"{name}"' for name in missing_names)
|
joined_names = ', '.join(f'"{name}"' for name in missing_names)
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Cannot restore database{'s' if len(missing_names) > 1 else ''} {joined_names} missing from borgmatic's configuration"
|
f"Cannot restore data source{'s' if len(missing_names) > 1 else ''} {joined_names} missing from borgmatic's configuration"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -263,7 +265,7 @@ def run_restore(
|
||||||
Run the "restore" action for the given repository, but only if the repository matches the
|
Run the "restore" action for the given repository, but only if the repository matches the
|
||||||
requested repository in restore arguments.
|
requested repository in restore arguments.
|
||||||
|
|
||||||
Raise ValueError if a configured database could not be found to restore.
|
Raise ValueError if a configured data source could not be found to restore.
|
||||||
'''
|
'''
|
||||||
if restore_arguments.repository and not borgmatic.config.validate.repositories_match(
|
if restore_arguments.repository and not borgmatic.config.validate.repositories_match(
|
||||||
repository, restore_arguments.repository
|
repository, restore_arguments.repository
|
||||||
|
@ -271,14 +273,14 @@ def run_restore(
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f'{repository.get("label", repository["path"])}: Restoring databases from archive {restore_arguments.archive}'
|
f'{repository.get("label", repository["path"])}: Restoring data sources from archive {restore_arguments.archive}'
|
||||||
)
|
)
|
||||||
|
|
||||||
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
||||||
'remove_database_dumps',
|
'remove_data_source_dumps',
|
||||||
config,
|
config,
|
||||||
repository['path'],
|
repository['path'],
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
global_arguments.dry_run,
|
global_arguments.dry_run,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -291,7 +293,7 @@ def run_restore(
|
||||||
local_path,
|
local_path,
|
||||||
remote_path,
|
remote_path,
|
||||||
)
|
)
|
||||||
archive_database_names = collect_archive_database_names(
|
archive_data_source_names = collect_archive_data_source_names(
|
||||||
repository['path'],
|
repository['path'],
|
||||||
archive_name,
|
archive_name,
|
||||||
config,
|
config,
|
||||||
|
@ -300,7 +302,9 @@ def run_restore(
|
||||||
local_path,
|
local_path,
|
||||||
remote_path,
|
remote_path,
|
||||||
)
|
)
|
||||||
restore_names = find_databases_to_restore(restore_arguments.databases, archive_database_names)
|
restore_names = find_data_sources_to_restore(
|
||||||
|
restore_arguments.data_sources, archive_data_source_names
|
||||||
|
)
|
||||||
found_names = set()
|
found_names = set()
|
||||||
remaining_restore_names = {}
|
remaining_restore_names = {}
|
||||||
connection_params = {
|
connection_params = {
|
||||||
|
@ -311,20 +315,20 @@ def run_restore(
|
||||||
'restore_path': restore_arguments.restore_path,
|
'restore_path': restore_arguments.restore_path,
|
||||||
}
|
}
|
||||||
|
|
||||||
for hook_name, database_names in restore_names.items():
|
for hook_name, data_source_names in restore_names.items():
|
||||||
for database_name in database_names:
|
for data_source_name in data_source_names:
|
||||||
found_hook_name, found_database = get_configured_database(
|
found_hook_name, found_data_source = get_configured_data_source(
|
||||||
config, archive_database_names, hook_name, database_name
|
config, archive_data_source_names, hook_name, data_source_name
|
||||||
)
|
)
|
||||||
|
|
||||||
if not found_database:
|
if not found_data_source:
|
||||||
remaining_restore_names.setdefault(found_hook_name or hook_name, []).append(
|
remaining_restore_names.setdefault(found_hook_name or hook_name, []).append(
|
||||||
database_name
|
data_source_name
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
found_names.add(database_name)
|
found_names.add(data_source_name)
|
||||||
restore_single_database(
|
restore_single_data_source(
|
||||||
repository,
|
repository,
|
||||||
config,
|
config,
|
||||||
local_borg_version,
|
local_borg_version,
|
||||||
|
@ -333,26 +337,26 @@ def run_restore(
|
||||||
remote_path,
|
remote_path,
|
||||||
archive_name,
|
archive_name,
|
||||||
found_hook_name or hook_name,
|
found_hook_name or hook_name,
|
||||||
dict(found_database, **{'schemas': restore_arguments.schemas}),
|
dict(found_data_source, **{'schemas': restore_arguments.schemas}),
|
||||||
connection_params,
|
connection_params,
|
||||||
)
|
)
|
||||||
|
|
||||||
# For any databases that weren't found via exact matches in the configuration, try to fallback
|
# For any data sources that weren't found via exact matches in the configuration, try to
|
||||||
# to "all" entries.
|
# fallback to "all" entries.
|
||||||
for hook_name, database_names in remaining_restore_names.items():
|
for hook_name, data_source_names in remaining_restore_names.items():
|
||||||
for database_name in database_names:
|
for data_source_name in data_source_names:
|
||||||
found_hook_name, found_database = get_configured_database(
|
found_hook_name, found_data_source = get_configured_data_source(
|
||||||
config, archive_database_names, hook_name, database_name, 'all'
|
config, archive_data_source_names, hook_name, data_source_name, 'all'
|
||||||
)
|
)
|
||||||
|
|
||||||
if not found_database:
|
if not found_data_source:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
found_names.add(database_name)
|
found_names.add(data_source_name)
|
||||||
database = copy.copy(found_database)
|
data_source = copy.copy(found_data_source)
|
||||||
database['name'] = database_name
|
data_source['name'] = data_source_name
|
||||||
|
|
||||||
restore_single_database(
|
restore_single_data_source(
|
||||||
repository,
|
repository,
|
||||||
config,
|
config,
|
||||||
local_borg_version,
|
local_borg_version,
|
||||||
|
@ -361,16 +365,16 @@ def run_restore(
|
||||||
remote_path,
|
remote_path,
|
||||||
archive_name,
|
archive_name,
|
||||||
found_hook_name or hook_name,
|
found_hook_name or hook_name,
|
||||||
dict(database, **{'schemas': restore_arguments.schemas}),
|
dict(data_source, **{'schemas': restore_arguments.schemas}),
|
||||||
connection_params,
|
connection_params,
|
||||||
)
|
)
|
||||||
|
|
||||||
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
||||||
'remove_database_dumps',
|
'remove_data_source_dumps',
|
||||||
config,
|
config,
|
||||||
repository['path'],
|
repository['path'],
|
||||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
borgmatic.hooks.dump.DATA_SOURCE_HOOK_NAMES,
|
||||||
global_arguments.dry_run,
|
global_arguments.dry_run,
|
||||||
)
|
)
|
||||||
|
|
||||||
ensure_databases_found(restore_names, remaining_restore_names, found_names)
|
ensure_data_sources_found(restore_names, remaining_restore_names, found_names)
|
||||||
|
|
|
@ -92,13 +92,13 @@ def capture_archive_listing(
|
||||||
config,
|
config,
|
||||||
local_borg_version,
|
local_borg_version,
|
||||||
global_arguments,
|
global_arguments,
|
||||||
list_path=None,
|
list_paths=None,
|
||||||
local_path='borg',
|
local_path='borg',
|
||||||
remote_path=None,
|
remote_path=None,
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Given a local or remote repository path, an archive name, a configuration dict, the local Borg
|
Given a local or remote repository path, an archive name, a configuration dict, the local Borg
|
||||||
version, global arguments as an argparse.Namespace, the archive path in which to list files, and
|
version, global arguments as an argparse.Namespace, the archive paths in which to list files, and
|
||||||
local and remote Borg paths, capture the output of listing that archive and return it as a list
|
local and remote Borg paths, capture the output of listing that archive and return it as a list
|
||||||
of file paths.
|
of file paths.
|
||||||
'''
|
'''
|
||||||
|
@ -113,7 +113,7 @@ def capture_archive_listing(
|
||||||
argparse.Namespace(
|
argparse.Namespace(
|
||||||
repository=repository_path,
|
repository=repository_path,
|
||||||
archive=archive,
|
archive=archive,
|
||||||
paths=[f'sh:{list_path}'],
|
paths=[f'sh:{path}' for path in list_paths] if list_paths else None,
|
||||||
find_paths=None,
|
find_paths=None,
|
||||||
json=None,
|
json=None,
|
||||||
format='{path}{NL}', # noqa: FS003
|
format='{path}{NL}', # noqa: FS003
|
||||||
|
|
|
@ -906,8 +906,8 @@ def make_parsers():
|
||||||
restore_parser = action_parsers.add_parser(
|
restore_parser = action_parsers.add_parser(
|
||||||
'restore',
|
'restore',
|
||||||
aliases=ACTION_ALIASES['restore'],
|
aliases=ACTION_ALIASES['restore'],
|
||||||
help='Restore database dumps from a named archive',
|
help='Restore data source (e.g. database) dumps from a named archive',
|
||||||
description='Restore database dumps from a named archive. (To extract files instead, use "borgmatic extract".)',
|
description='Restore data source (e.g. database) dumps from a named archive. (To extract files instead, use "borgmatic extract".)',
|
||||||
add_help=False,
|
add_help=False,
|
||||||
)
|
)
|
||||||
restore_group = restore_parser.add_argument_group('restore arguments')
|
restore_group = restore_parser.add_argument_group('restore arguments')
|
||||||
|
@ -919,18 +919,19 @@ def make_parsers():
|
||||||
'--archive', help='Name of archive to restore from (or "latest")', required=True
|
'--archive', help='Name of archive to restore from (or "latest")', required=True
|
||||||
)
|
)
|
||||||
restore_group.add_argument(
|
restore_group.add_argument(
|
||||||
|
'--data-source',
|
||||||
'--database',
|
'--database',
|
||||||
metavar='NAME',
|
metavar='NAME',
|
||||||
dest='databases',
|
dest='data_sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Name of database to restore from archive, must be defined in borgmatic's configuration, can specify flag multiple times, defaults to all databases",
|
help="Name of data source (e.g. database) to restore from archive, must be defined in borgmatic's configuration, can specify flag multiple times, defaults to all databases",
|
||||||
)
|
)
|
||||||
restore_group.add_argument(
|
restore_group.add_argument(
|
||||||
'--schema',
|
'--schema',
|
||||||
metavar='NAME',
|
metavar='NAME',
|
||||||
dest='schemas',
|
dest='schemas',
|
||||||
action='append',
|
action='append',
|
||||||
help='Name of schema to restore from the database, can specify flag multiple times, defaults to all schemas. Schemas are only supported for PostgreSQL and MongoDB databases',
|
help='Name of schema to restore from the data source, can specify flag multiple times, defaults to all schemas. Schemas are only supported for PostgreSQL and MongoDB databases',
|
||||||
)
|
)
|
||||||
restore_group.add_argument(
|
restore_group.add_argument(
|
||||||
'--hostname',
|
'--hostname',
|
||||||
|
@ -938,7 +939,7 @@ def make_parsers():
|
||||||
)
|
)
|
||||||
restore_group.add_argument(
|
restore_group.add_argument(
|
||||||
'--port',
|
'--port',
|
||||||
help='Port to restore to. Defaults to the "restore_port" option in borgmatic\'s configuration',
|
help='Database port to restore to. Defaults to the "restore_port" option in borgmatic\'s configuration',
|
||||||
)
|
)
|
||||||
restore_group.add_argument(
|
restore_group.add_argument(
|
||||||
'--username',
|
'--username',
|
||||||
|
|
|
@ -6,7 +6,7 @@ from borgmatic.borg.state import DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
DATABASE_HOOK_NAMES = (
|
DATA_SOURCE_HOOK_NAMES = (
|
||||||
'mariadb_databases',
|
'mariadb_databases',
|
||||||
'mysql_databases',
|
'mysql_databases',
|
||||||
'mongodb_databases',
|
'mongodb_databases',
|
||||||
|
@ -15,26 +15,26 @@ DATABASE_HOOK_NAMES = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_path(borgmatic_source_directory, database_hook_name):
|
def make_data_source_dump_path(borgmatic_source_directory, data_source_hook_name):
|
||||||
'''
|
'''
|
||||||
Given a borgmatic source directory (or None) and a database hook name, construct a database dump
|
Given a borgmatic source directory (or None) and a data source hook name, construct a data
|
||||||
path.
|
source dump path.
|
||||||
'''
|
'''
|
||||||
if not borgmatic_source_directory:
|
if not borgmatic_source_directory:
|
||||||
borgmatic_source_directory = DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
borgmatic_source_directory = DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||||
|
|
||||||
return os.path.join(borgmatic_source_directory, database_hook_name)
|
return os.path.join(borgmatic_source_directory, data_source_hook_name)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_filename(dump_path, name, hostname=None):
|
def make_data_source_dump_filename(dump_path, name, hostname=None):
|
||||||
'''
|
'''
|
||||||
Based on the given dump directory path, database name, and hostname, return a filename to use
|
Based on the given dump directory path, data source name, and hostname, return a filename to use
|
||||||
for the database dump. The hostname defaults to localhost.
|
for the data source dump. The hostname defaults to localhost.
|
||||||
|
|
||||||
Raise ValueError if the database name is invalid.
|
Raise ValueError if the data source name is invalid.
|
||||||
'''
|
'''
|
||||||
if os.path.sep in name:
|
if os.path.sep in name:
|
||||||
raise ValueError(f'Invalid database name {name}')
|
raise ValueError(f'Invalid data source name {name}')
|
||||||
|
|
||||||
return os.path.join(os.path.expanduser(dump_path), hostname or 'localhost', name)
|
return os.path.join(os.path.expanduser(dump_path), hostname or 'localhost', name)
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ def create_named_pipe_for_dump(dump_path):
|
||||||
os.mkfifo(dump_path, mode=0o600)
|
os.mkfifo(dump_path, mode=0o600)
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(dump_path, database_type_name, log_prefix, dry_run):
|
def remove_data_source_dumps(dump_path, data_source_type_name, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Remove all database dumps in the given dump directory path (including the directory itself). If
|
Remove all data source dumps in the given dump directory path (including the directory itself).
|
||||||
this is a dry run, then don't actually remove anything.
|
If this is a dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually removing anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually removing anything)' if dry_run else ''
|
||||||
|
|
||||||
logger.debug(f'{log_prefix}: Removing {database_type_name} database dumps{dry_run_label}')
|
logger.debug(f'{log_prefix}: Removing {data_source_type_name} data source dumps{dry_run_label}')
|
||||||
|
|
||||||
expanded_path = os.path.expanduser(dump_path)
|
expanded_path = os.path.expanduser(dump_path)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ def make_dump_path(config): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make the dump path from the given configuration dict and the name of this hook.
|
Make the dump path from the given configuration dict and the name of this hook.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_path(
|
return dump.make_data_source_dump_path(
|
||||||
config.get('borgmatic_source_directory'), 'mariadb_databases'
|
config.get('borgmatic_source_directory'), 'mariadb_databases'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ def execute_dump_command(
|
||||||
this is a dry run, then don't actually dump anything and return None.
|
this is a dry run, then don't actually dump anything and return None.
|
||||||
'''
|
'''
|
||||||
database_name = database['name']
|
database_name = database['name']
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
dump_path, database['name'], database.get('hostname')
|
dump_path, database['name'], database.get('hostname')
|
||||||
)
|
)
|
||||||
if os.path.exists(dump_filename):
|
if os.path.exists(dump_filename):
|
||||||
|
@ -106,7 +106,7 @@ def execute_dump_command(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def dump_databases(databases, config, log_prefix, dry_run):
|
def dump_data_sources(databases, config, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Dump the given MariaDB databases to a named pipe. The databases are supplied as a sequence of
|
Dump the given MariaDB databases to a named pipe. The databases are supplied as a sequence of
|
||||||
dicts, one dict describing each database as per the configuration schema. Use the given
|
dicts, one dict describing each database as per the configuration schema. Use the given
|
||||||
|
@ -165,49 +165,55 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
return [process for process in processes if process]
|
return [process for process in processes if process]
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
def remove_data_source_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Remove all database dump files for this hook regardless of the given databases. Use the given
|
Remove all database dump files for this hook regardless of the given databases. Use the given
|
||||||
configuration dict to construct the destination path and the log prefix in any log entries. If
|
configuration dict to construct the destination path and the log prefix in any log entries. If
|
||||||
this is a dry run, then don't actually remove anything.
|
this is a dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dump.remove_database_dumps(make_dump_path(config), 'MariaDB', log_prefix, dry_run)
|
dump.remove_data_source_dumps(make_dump_path(config), 'MariaDB', log_prefix, dry_run)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
def make_data_source_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
||||||
database name to match, return the corresponding glob patterns to match the database dump in an
|
database name to match, return the corresponding glob patterns to match the database dump in an
|
||||||
archive.
|
archive.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_filename(make_dump_path(config), name, hostname='*')
|
return dump.make_data_source_dump_filename(make_dump_path(config), name, hostname='*')
|
||||||
|
|
||||||
|
|
||||||
def restore_database_dump(
|
def restore_data_source_dump(
|
||||||
hook_config, config, log_prefix, database, dry_run, extract_process, connection_params
|
hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Restore a database from the given extract stream. The database is supplied as a configuration
|
Restore a database from the given extract stream. The database is supplied as a data source
|
||||||
dict, but the given hook configuration is ignored. The given configuration dict is used to
|
configuration dict, but the given hook configuration is ignored. The given configuration dict is
|
||||||
construct the destination path, and the given log prefix is used for any log entries. If this is
|
used to construct the destination path, and the given log prefix is used for any log entries. If
|
||||||
a dry run, then don't actually restore anything. Trigger the given active extract process (an
|
this is a dry run, then don't actually restore anything. Trigger the given active extract
|
||||||
instance of subprocess.Popen) to produce output to consume.
|
process (an instance of subprocess.Popen) to produce output to consume.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
||||||
hostname = connection_params['hostname'] or database.get(
|
hostname = connection_params['hostname'] or data_source.get(
|
||||||
'restore_hostname', database.get('hostname')
|
'restore_hostname', data_source.get('hostname')
|
||||||
)
|
)
|
||||||
port = str(connection_params['port'] or database.get('restore_port', database.get('port', '')))
|
port = str(
|
||||||
username = connection_params['username'] or database.get(
|
connection_params['port'] or data_source.get('restore_port', data_source.get('port', ''))
|
||||||
'restore_username', database.get('username')
|
|
||||||
)
|
)
|
||||||
password = connection_params['password'] or database.get(
|
username = connection_params['username'] or data_source.get(
|
||||||
'restore_password', database.get('password')
|
'restore_username', data_source.get('username')
|
||||||
|
)
|
||||||
|
password = connection_params['password'] or data_source.get(
|
||||||
|
'restore_password', data_source.get('password')
|
||||||
)
|
)
|
||||||
|
|
||||||
restore_command = (
|
restore_command = (
|
||||||
('mariadb', '--batch')
|
('mariadb', '--batch')
|
||||||
+ (tuple(database['restore_options'].split(' ')) if 'restore_options' in database else ())
|
+ (
|
||||||
|
tuple(data_source['restore_options'].split(' '))
|
||||||
|
if 'restore_options' in data_source
|
||||||
|
else ()
|
||||||
|
)
|
||||||
+ (('--host', hostname) if hostname else ())
|
+ (('--host', hostname) if hostname else ())
|
||||||
+ (('--port', str(port)) if port else ())
|
+ (('--port', str(port)) if port else ())
|
||||||
+ (('--protocol', 'tcp') if hostname or port else ())
|
+ (('--protocol', 'tcp') if hostname or port else ())
|
||||||
|
@ -215,7 +221,7 @@ def restore_database_dump(
|
||||||
)
|
)
|
||||||
extra_environment = {'MYSQL_PWD': password} if password else None
|
extra_environment = {'MYSQL_PWD': password} if password else None
|
||||||
|
|
||||||
logger.debug(f"{log_prefix}: Restoring MariaDB database {database['name']}{dry_run_label}")
|
logger.debug(f"{log_prefix}: Restoring MariaDB database {data_source['name']}{dry_run_label}")
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,12 @@ def make_dump_path(config): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make the dump path from the given configuration dict and the name of this hook.
|
Make the dump path from the given configuration dict and the name of this hook.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_path(
|
return dump.make_data_source_dump_path(
|
||||||
config.get('borgmatic_source_directory'), 'mongodb_databases'
|
config.get('borgmatic_source_directory'), 'mongodb_databases'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def dump_databases(databases, config, log_prefix, dry_run):
|
def dump_data_sources(databases, config, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Dump the given MongoDB databases to a named pipe. The databases are supplied as a sequence of
|
Dump the given MongoDB databases to a named pipe. The databases are supplied as a sequence of
|
||||||
dicts, one dict describing each database as per the configuration schema. Use the configuration
|
dicts, one dict describing each database as per the configuration schema. Use the configuration
|
||||||
|
@ -31,7 +31,7 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
processes = []
|
processes = []
|
||||||
for database in databases:
|
for database in databases:
|
||||||
name = database['name']
|
name = database['name']
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
make_dump_path(config), name, database.get('hostname')
|
make_dump_path(config), name, database.get('hostname')
|
||||||
)
|
)
|
||||||
dump_format = database.get('format', 'archive')
|
dump_format = database.get('format', 'archive')
|
||||||
|
@ -78,46 +78,46 @@ def build_dump_command(database, dump_filename, dump_format):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
def remove_data_source_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Remove all database dump files for this hook regardless of the given databases. Use the log
|
Remove all database dump files for this hook regardless of the given databases. Use the log
|
||||||
prefix in any log entries. Use the given configuration dict to construct the destination path.
|
prefix in any log entries. Use the given configuration dict to construct the destination path.
|
||||||
If this is a dry run, then don't actually remove anything.
|
If this is a dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dump.remove_database_dumps(make_dump_path(config), 'MongoDB', log_prefix, dry_run)
|
dump.remove_data_source_dumps(make_dump_path(config), 'MongoDB', log_prefix, dry_run)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
def make_data_source_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Given a sequence of database configurations dicts, a configuration dict, a prefix to log with,
|
Given a sequence of database configurations dicts, a configuration dict, a prefix to log with,
|
||||||
and a database name to match, return the corresponding glob patterns to match the database dump
|
and a database name to match, return the corresponding glob patterns to match the database dump
|
||||||
in an archive.
|
in an archive.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_filename(make_dump_path(config), name, hostname='*')
|
return dump.make_data_source_dump_filename(make_dump_path(config), name, hostname='*')
|
||||||
|
|
||||||
|
|
||||||
def restore_database_dump(
|
def restore_data_source_dump(
|
||||||
hook_config, config, log_prefix, database, dry_run, extract_process, connection_params
|
hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Restore a database from the given extract stream. The database is supplied as a configuration
|
Restore a database from the given extract stream. The database is supplied as a data source
|
||||||
dict, but the given hook configuration is ignored. The given configuration dict is used to
|
configuration dict, but the given hook configuration is ignored. The given configuration dict is
|
||||||
construct the destination path, and the given log prefix is used for any log entries. If this is
|
used to construct the destination path, and the given log prefix is used for any log entries. If
|
||||||
a dry run, then don't actually restore anything. Trigger the given active extract process (an
|
this is a dry run, then don't actually restore anything. Trigger the given active extract
|
||||||
instance of subprocess.Popen) to produce output to consume.
|
process (an instance of subprocess.Popen) to produce output to consume.
|
||||||
|
|
||||||
If the extract process is None, then restore the dump from the filesystem rather than from an
|
If the extract process is None, then restore the dump from the filesystem rather than from an
|
||||||
extract stream.
|
extract stream.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
make_dump_path(config), database['name'], database.get('hostname')
|
make_dump_path(config), data_source['name'], data_source.get('hostname')
|
||||||
)
|
)
|
||||||
restore_command = build_restore_command(
|
restore_command = build_restore_command(
|
||||||
extract_process, database, dump_filename, connection_params
|
extract_process, data_source, dump_filename, connection_params
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f"{log_prefix}: Restoring MongoDB database {database['name']}{dry_run_label}")
|
logger.debug(f"{log_prefix}: Restoring MongoDB database {data_source['name']}{dry_run_label}")
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,9 @@ def make_dump_path(config): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make the dump path from the given configuration dict and the name of this hook.
|
Make the dump path from the given configuration dict and the name of this hook.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_path(config.get('borgmatic_source_directory'), 'mysql_databases')
|
return dump.make_data_source_dump_path(
|
||||||
|
config.get('borgmatic_source_directory'), 'mysql_databases'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
SYSTEM_DATABASE_NAMES = ('information_schema', 'mysql', 'performance_schema', 'sys')
|
SYSTEM_DATABASE_NAMES = ('information_schema', 'mysql', 'performance_schema', 'sys')
|
||||||
|
@ -67,7 +69,7 @@ def execute_dump_command(
|
||||||
this is a dry run, then don't actually dump anything and return None.
|
this is a dry run, then don't actually dump anything and return None.
|
||||||
'''
|
'''
|
||||||
database_name = database['name']
|
database_name = database['name']
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
dump_path, database['name'], database.get('hostname')
|
dump_path, database['name'], database.get('hostname')
|
||||||
)
|
)
|
||||||
if os.path.exists(dump_filename):
|
if os.path.exists(dump_filename):
|
||||||
|
@ -104,7 +106,7 @@ def execute_dump_command(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def dump_databases(databases, config, log_prefix, dry_run):
|
def dump_data_sources(databases, config, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Dump the given MySQL/MariaDB databases to a named pipe. The databases are supplied as a sequence
|
Dump the given MySQL/MariaDB databases to a named pipe. The databases are supplied as a sequence
|
||||||
of dicts, one dict describing each database as per the configuration schema. Use the given
|
of dicts, one dict describing each database as per the configuration schema. Use the given
|
||||||
|
@ -162,49 +164,55 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
return [process for process in processes if process]
|
return [process for process in processes if process]
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
def remove_data_source_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Remove all database dump files for this hook regardless of the given databases. Use the given
|
Remove all database dump files for this hook regardless of the given databases. Use the given
|
||||||
configuration dict to construct the destination path and the log prefix in any log entries. If
|
configuration dict to construct the destination path and the log prefix in any log entries. If
|
||||||
this is a dry run, then don't actually remove anything.
|
this is a dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dump.remove_database_dumps(make_dump_path(config), 'MySQL', log_prefix, dry_run)
|
dump.remove_data_source_dumps(make_dump_path(config), 'MySQL', log_prefix, dry_run)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
def make_data_source_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
||||||
database name to match, return the corresponding glob patterns to match the database dump in an
|
database name to match, return the corresponding glob patterns to match the database dump in an
|
||||||
archive.
|
archive.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_filename(make_dump_path(config), name, hostname='*')
|
return dump.make_data_source_dump_filename(make_dump_path(config), name, hostname='*')
|
||||||
|
|
||||||
|
|
||||||
def restore_database_dump(
|
def restore_data_source_dump(
|
||||||
hook_config, config, log_prefix, database, dry_run, extract_process, connection_params
|
hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Restore a database from the given extract stream. The database is supplied as a configuration
|
Restore a database from the given extract stream. The database is supplied as a data source
|
||||||
dict, but the given hook configuration is ignored. The given configuration dict is used to
|
configuration dict, but the given hook configuration is ignored. The given configuration dict is
|
||||||
construct the destination path, and the given log prefix is used for any log entries. If this is
|
used to construct the destination path, and the given log prefix is used for any log entries. If
|
||||||
a dry run, then don't actually restore anything. Trigger the given active extract process (an
|
this is a dry run, then don't actually restore anything. Trigger the given active extract
|
||||||
instance of subprocess.Popen) to produce output to consume.
|
process (an instance of subprocess.Popen) to produce output to consume.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
||||||
hostname = connection_params['hostname'] or database.get(
|
hostname = connection_params['hostname'] or data_source.get(
|
||||||
'restore_hostname', database.get('hostname')
|
'restore_hostname', data_source.get('hostname')
|
||||||
)
|
)
|
||||||
port = str(connection_params['port'] or database.get('restore_port', database.get('port', '')))
|
port = str(
|
||||||
username = connection_params['username'] or database.get(
|
connection_params['port'] or data_source.get('restore_port', data_source.get('port', ''))
|
||||||
'restore_username', database.get('username')
|
|
||||||
)
|
)
|
||||||
password = connection_params['password'] or database.get(
|
username = connection_params['username'] or data_source.get(
|
||||||
'restore_password', database.get('password')
|
'restore_username', data_source.get('username')
|
||||||
|
)
|
||||||
|
password = connection_params['password'] or data_source.get(
|
||||||
|
'restore_password', data_source.get('password')
|
||||||
)
|
)
|
||||||
|
|
||||||
restore_command = (
|
restore_command = (
|
||||||
('mysql', '--batch')
|
('mysql', '--batch')
|
||||||
+ (tuple(database['restore_options'].split(' ')) if 'restore_options' in database else ())
|
+ (
|
||||||
|
tuple(data_source['restore_options'].split(' '))
|
||||||
|
if 'restore_options' in data_source
|
||||||
|
else ()
|
||||||
|
)
|
||||||
+ (('--host', hostname) if hostname else ())
|
+ (('--host', hostname) if hostname else ())
|
||||||
+ (('--port', str(port)) if port else ())
|
+ (('--port', str(port)) if port else ())
|
||||||
+ (('--protocol', 'tcp') if hostname or port else ())
|
+ (('--protocol', 'tcp') if hostname or port else ())
|
||||||
|
@ -212,7 +220,7 @@ def restore_database_dump(
|
||||||
)
|
)
|
||||||
extra_environment = {'MYSQL_PWD': password} if password else None
|
extra_environment = {'MYSQL_PWD': password} if password else None
|
||||||
|
|
||||||
logger.debug(f"{log_prefix}: Restoring MySQL database {database['name']}{dry_run_label}")
|
logger.debug(f"{log_prefix}: Restoring MySQL database {data_source['name']}{dry_run_label}")
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ def make_dump_path(config): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make the dump path from the given configuration dict and the name of this hook.
|
Make the dump path from the given configuration dict and the name of this hook.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_path(
|
return dump.make_data_source_dump_path(
|
||||||
config.get('borgmatic_source_directory'), 'postgresql_databases'
|
config.get('borgmatic_source_directory'), 'postgresql_databases'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ def database_names_to_dump(database, extra_environment, log_prefix, dry_run):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def dump_databases(databases, config, log_prefix, dry_run):
|
def dump_data_sources(databases, config, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Dump the given PostgreSQL databases to a named pipe. The databases are supplied as a sequence of
|
Dump the given PostgreSQL databases to a named pipe. The databases are supplied as a sequence of
|
||||||
dicts, one dict describing each database as per the configuration schema. Use the given
|
dicts, one dict describing each database as per the configuration schema. Use the given
|
||||||
|
@ -126,7 +126,7 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
dump_format = database.get('format', None if database_name == 'all' else 'custom')
|
dump_format = database.get('format', None if database_name == 'all' else 'custom')
|
||||||
default_dump_command = 'pg_dumpall' if database_name == 'all' else 'pg_dump'
|
default_dump_command = 'pg_dumpall' if database_name == 'all' else 'pg_dump'
|
||||||
dump_command = database.get('pg_dump_command') or default_dump_command
|
dump_command = database.get('pg_dump_command') or default_dump_command
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
dump_path, database_name, database.get('hostname')
|
dump_path, database_name, database.get('hostname')
|
||||||
)
|
)
|
||||||
if os.path.exists(dump_filename):
|
if os.path.exists(dump_filename):
|
||||||
|
@ -183,33 +183,33 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
return processes
|
return processes
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
def remove_data_source_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Remove all database dump files for this hook regardless of the given databases. Use the given
|
Remove all database dump files for this hook regardless of the given databases. Use the given
|
||||||
configuration dict to construct the destination path and the log prefix in any log entries. If
|
configuration dict to construct the destination path and the log prefix in any log entries. If
|
||||||
this is a dry run, then don't actually remove anything.
|
this is a dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dump.remove_database_dumps(make_dump_path(config), 'PostgreSQL', log_prefix, dry_run)
|
dump.remove_data_source_dumps(make_dump_path(config), 'PostgreSQL', log_prefix, dry_run)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
def make_data_source_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
Given a sequence of configurations dicts, a configuration dict, a prefix to log with, and a
|
||||||
database name to match, return the corresponding glob patterns to match the database dump in an
|
database name to match, return the corresponding glob patterns to match the database dump in an
|
||||||
archive.
|
archive.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_filename(make_dump_path(config), name, hostname='*')
|
return dump.make_data_source_dump_filename(make_dump_path(config), name, hostname='*')
|
||||||
|
|
||||||
|
|
||||||
def restore_database_dump(
|
def restore_data_source_dump(
|
||||||
hook_config, config, log_prefix, database, dry_run, extract_process, connection_params
|
hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Restore a database from the given extract stream. The database is supplied as a configuration
|
Restore a database from the given extract stream. The database is supplied as a data source
|
||||||
dict, but the given hook configuration is ignored. The given configuration dict is used to
|
configuration dict, but the given hook configuration is ignored. The given configuration dict is
|
||||||
construct the destination path, and the given log prefix is used for any log entries. If this is
|
used to construct the destination path, and the given log prefix is used for any log entries. If
|
||||||
a dry run, then don't actually restore anything. Trigger the given active extract process (an
|
this is a dry run, then don't actually restore anything. Trigger the given active extract
|
||||||
instance of subprocess.Popen) to produce output to consume.
|
process (an instance of subprocess.Popen) to produce output to consume.
|
||||||
|
|
||||||
If the extract process is None, then restore the dump from the filesystem rather than from an
|
If the extract process is None, then restore the dump from the filesystem rather than from an
|
||||||
extract stream.
|
extract stream.
|
||||||
|
@ -218,54 +218,66 @@ def restore_database_dump(
|
||||||
hostname, port, username, and password.
|
hostname, port, username, and password.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
||||||
hostname = connection_params['hostname'] or database.get(
|
hostname = connection_params['hostname'] or data_source.get(
|
||||||
'restore_hostname', database.get('hostname')
|
'restore_hostname', data_source.get('hostname')
|
||||||
)
|
)
|
||||||
port = str(connection_params['port'] or database.get('restore_port', database.get('port', '')))
|
port = str(
|
||||||
username = connection_params['username'] or database.get(
|
connection_params['port'] or data_source.get('restore_port', data_source.get('port', ''))
|
||||||
'restore_username', database.get('username')
|
)
|
||||||
|
username = connection_params['username'] or data_source.get(
|
||||||
|
'restore_username', data_source.get('username')
|
||||||
)
|
)
|
||||||
|
|
||||||
all_databases = bool(database['name'] == 'all')
|
all_databases = bool(data_source['name'] == 'all')
|
||||||
dump_filename = dump.make_database_dump_filename(
|
dump_filename = dump.make_data_source_dump_filename(
|
||||||
make_dump_path(config), database['name'], database.get('hostname')
|
make_dump_path(config), data_source['name'], data_source.get('hostname')
|
||||||
)
|
)
|
||||||
psql_command = shlex.split(database.get('psql_command') or 'psql')
|
psql_command = shlex.split(data_source.get('psql_command') or 'psql')
|
||||||
analyze_command = (
|
analyze_command = (
|
||||||
tuple(psql_command)
|
tuple(psql_command)
|
||||||
+ ('--no-password', '--no-psqlrc', '--quiet')
|
+ ('--no-password', '--no-psqlrc', '--quiet')
|
||||||
+ (('--host', hostname) if hostname else ())
|
+ (('--host', hostname) if hostname else ())
|
||||||
+ (('--port', port) if port else ())
|
+ (('--port', port) if port else ())
|
||||||
+ (('--username', username) if username else ())
|
+ (('--username', username) if username else ())
|
||||||
+ (('--dbname', database['name']) if not all_databases else ())
|
+ (('--dbname', data_source['name']) if not all_databases else ())
|
||||||
+ (tuple(database['analyze_options'].split(' ')) if 'analyze_options' in database else ())
|
+ (
|
||||||
|
tuple(data_source['analyze_options'].split(' '))
|
||||||
|
if 'analyze_options' in data_source
|
||||||
|
else ()
|
||||||
|
)
|
||||||
+ ('--command', 'ANALYZE')
|
+ ('--command', 'ANALYZE')
|
||||||
)
|
)
|
||||||
use_psql_command = all_databases or database.get('format') == 'plain'
|
use_psql_command = all_databases or data_source.get('format') == 'plain'
|
||||||
pg_restore_command = shlex.split(database.get('pg_restore_command') or 'pg_restore')
|
pg_restore_command = shlex.split(data_source.get('pg_restore_command') or 'pg_restore')
|
||||||
restore_command = (
|
restore_command = (
|
||||||
tuple(psql_command if use_psql_command else pg_restore_command)
|
tuple(psql_command if use_psql_command else pg_restore_command)
|
||||||
+ ('--no-password',)
|
+ ('--no-password',)
|
||||||
+ (('--no-psqlrc',) if use_psql_command else ('--if-exists', '--exit-on-error', '--clean'))
|
+ (('--no-psqlrc',) if use_psql_command else ('--if-exists', '--exit-on-error', '--clean'))
|
||||||
+ (('--dbname', database['name']) if not all_databases else ())
|
+ (('--dbname', data_source['name']) if not all_databases else ())
|
||||||
+ (('--host', hostname) if hostname else ())
|
+ (('--host', hostname) if hostname else ())
|
||||||
+ (('--port', port) if port else ())
|
+ (('--port', port) if port else ())
|
||||||
+ (('--username', username) if username else ())
|
+ (('--username', username) if username else ())
|
||||||
+ (('--no-owner',) if database.get('no_owner', False) else ())
|
+ (('--no-owner',) if data_source.get('no_owner', False) else ())
|
||||||
+ (tuple(database['restore_options'].split(' ')) if 'restore_options' in database else ())
|
+ (
|
||||||
|
tuple(data_source['restore_options'].split(' '))
|
||||||
|
if 'restore_options' in data_source
|
||||||
|
else ()
|
||||||
|
)
|
||||||
+ (() if extract_process else (dump_filename,))
|
+ (() if extract_process else (dump_filename,))
|
||||||
+ tuple(
|
+ tuple(
|
||||||
itertools.chain.from_iterable(('--schema', schema) for schema in database['schemas'])
|
itertools.chain.from_iterable(('--schema', schema) for schema in data_source['schemas'])
|
||||||
if database.get('schemas')
|
if data_source.get('schemas')
|
||||||
else ()
|
else ()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
extra_environment = make_extra_environment(
|
extra_environment = make_extra_environment(
|
||||||
database, restore_connection_params=connection_params
|
data_source, restore_connection_params=connection_params
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f"{log_prefix}: Restoring PostgreSQL database {database['name']}{dry_run_label}")
|
logger.debug(
|
||||||
|
f"{log_prefix}: Restoring PostgreSQL database {data_source['name']}{dry_run_label}"
|
||||||
|
)
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,12 @@ def make_dump_path(config): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make the dump path from the given configuration dict and the name of this hook.
|
Make the dump path from the given configuration dict and the name of this hook.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_path(
|
return dump.make_data_source_dump_path(
|
||||||
config.get('borgmatic_source_directory'), 'sqlite_databases'
|
config.get('borgmatic_source_directory'), 'sqlite_databases'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def dump_databases(databases, config, log_prefix, dry_run):
|
def dump_data_sources(databases, config, log_prefix, dry_run):
|
||||||
'''
|
'''
|
||||||
Dump the given SQLite3 databases to a file. The databases are supplied as a sequence of
|
Dump the given SQLite3 databases to a file. The databases are supplied as a sequence of
|
||||||
configuration dicts, as per the configuration schema. Use the given configuration dict to
|
configuration dicts, as per the configuration schema. Use the given configuration dict to
|
||||||
|
@ -39,7 +39,7 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
)
|
)
|
||||||
|
|
||||||
dump_path = make_dump_path(config)
|
dump_path = make_dump_path(config)
|
||||||
dump_filename = dump.make_database_dump_filename(dump_path, database['name'])
|
dump_filename = dump.make_data_source_dump_filename(dump_path, database['name'])
|
||||||
if os.path.exists(dump_filename):
|
if os.path.exists(dump_filename):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f'{log_prefix}: Skipping duplicate dump of SQLite database at {database_path} to {dump_filename}'
|
f'{log_prefix}: Skipping duplicate dump of SQLite database at {database_path} to {dump_filename}'
|
||||||
|
@ -65,37 +65,37 @@ def dump_databases(databases, config, log_prefix, dry_run):
|
||||||
return processes
|
return processes
|
||||||
|
|
||||||
|
|
||||||
def remove_database_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
def remove_data_source_dumps(databases, config, log_prefix, dry_run): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Remove the given SQLite3 database dumps from the filesystem. The databases are supplied as a
|
Remove the given SQLite3 database dumps from the filesystem. The databases are supplied as a
|
||||||
sequence of configuration dicts, as per the configuration schema. Use the given configuration
|
sequence of configuration dicts, as per the configuration schema. Use the given configuration
|
||||||
dict to construct the destination path and the given log prefix in any log entries. If this is a
|
dict to construct the destination path and the given log prefix in any log entries. If this is a
|
||||||
dry run, then don't actually remove anything.
|
dry run, then don't actually remove anything.
|
||||||
'''
|
'''
|
||||||
dump.remove_database_dumps(make_dump_path(config), 'SQLite', log_prefix, dry_run)
|
dump.remove_data_source_dumps(make_dump_path(config), 'SQLite', log_prefix, dry_run)
|
||||||
|
|
||||||
|
|
||||||
def make_database_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
def make_data_source_dump_pattern(databases, config, log_prefix, name=None): # pragma: no cover
|
||||||
'''
|
'''
|
||||||
Make a pattern that matches the given SQLite3 databases. The databases are supplied as a
|
Make a pattern that matches the given SQLite3 databases. The databases are supplied as a
|
||||||
sequence of configuration dicts, as per the configuration schema.
|
sequence of configuration dicts, as per the configuration schema.
|
||||||
'''
|
'''
|
||||||
return dump.make_database_dump_filename(make_dump_path(config), name)
|
return dump.make_data_source_dump_filename(make_dump_path(config), name)
|
||||||
|
|
||||||
|
|
||||||
def restore_database_dump(
|
def restore_data_source_dump(
|
||||||
hook_config, config, log_prefix, database, dry_run, extract_process, connection_params
|
hook_config, config, log_prefix, data_source, dry_run, extract_process, connection_params
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Restore a database from the given extract stream. The database is supplied as a configuration
|
Restore a database from the given extract stream. The database is supplied as a data source
|
||||||
dict, but the given hook configuration is ignored. The given configuration dict is used to
|
configuration dict, but the given hook configuration is ignored. The given configuration dict is
|
||||||
construct the destination path, and the given log prefix is used for any log entries. If this is
|
used to construct the destination path, and the given log prefix is used for any log entries. If
|
||||||
a dry run, then don't actually restore anything. Trigger the given active extract process (an
|
this is a dry run, then don't actually restore anything. Trigger the given active extract
|
||||||
instance of subprocess.Popen) to produce output to consume.
|
process (an instance of subprocess.Popen) to produce output to consume.
|
||||||
'''
|
'''
|
||||||
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
|
||||||
database_path = connection_params['restore_path'] or database.get(
|
database_path = connection_params['restore_path'] or data_source.get(
|
||||||
'restore_path', database.get('path')
|
'restore_path', data_source.get('path')
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f'{log_prefix}: Restoring SQLite database at {database_path}{dry_run_label}')
|
logger.debug(f'{log_prefix}: Restoring SQLite database at {database_path}{dry_run_label}')
|
||||||
|
|
|
@ -4,69 +4,71 @@ from flexmock import flexmock
|
||||||
import borgmatic.actions.restore as module
|
import borgmatic.actions.restore as module
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_matches_database_by_name():
|
def test_get_configured_data_source_matches_data_source_by_name():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={
|
config={
|
||||||
'other_databases': [{'name': 'other'}],
|
'other_databases': [{'name': 'other'}],
|
||||||
'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}],
|
'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}],
|
||||||
},
|
},
|
||||||
archive_database_names={'postgresql_databases': ['other', 'foo', 'bar']},
|
archive_data_source_names={'postgresql_databases': ['other', 'foo', 'bar']},
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
) == ('postgresql_databases', {'name': 'bar'})
|
) == ('postgresql_databases', {'name': 'bar'})
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_matches_nothing_when_nothing_configured():
|
def test_get_configured_data_source_matches_nothing_when_nothing_configured():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={},
|
config={},
|
||||||
archive_database_names={'postgresql_databases': ['foo']},
|
archive_data_source_names={'postgresql_databases': ['foo']},
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='quux',
|
data_source_name='quux',
|
||||||
) == (None, None)
|
) == (None, None)
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_matches_nothing_when_database_name_not_configured():
|
def test_get_configured_data_source_matches_nothing_when_data_source_name_not_configured():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}]},
|
config={'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}]},
|
||||||
archive_database_names={'postgresql_databases': ['foo']},
|
archive_data_source_names={'postgresql_databases': ['foo']},
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='quux',
|
data_source_name='quux',
|
||||||
) == (None, None)
|
) == (None, None)
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_matches_nothing_when_database_name_not_in_archive():
|
def test_get_configured_data_source_matches_nothing_when_data_source_name_not_in_archive():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}]},
|
config={'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}]},
|
||||||
archive_database_names={'postgresql_databases': ['bar']},
|
archive_data_source_names={'postgresql_databases': ['bar']},
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='foo',
|
data_source_name='foo',
|
||||||
) == (None, None)
|
) == (None, None)
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_matches_database_by_configuration_database_name():
|
def test_get_configured_data_source_matches_data_source_by_configuration_data_source_name():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={'postgresql_databases': [{'name': 'all'}, {'name': 'bar'}]},
|
config={'postgresql_databases': [{'name': 'all'}, {'name': 'bar'}]},
|
||||||
archive_database_names={'postgresql_databases': ['foo']},
|
archive_data_source_names={'postgresql_databases': ['foo']},
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='foo',
|
data_source_name='foo',
|
||||||
configuration_database_name='all',
|
configuration_data_source_name='all',
|
||||||
) == ('postgresql_databases', {'name': 'all'})
|
) == ('postgresql_databases', {'name': 'all'})
|
||||||
|
|
||||||
|
|
||||||
def test_get_configured_database_with_unspecified_hook_matches_database_by_name():
|
def test_get_configured_data_source_with_unspecified_hook_matches_data_source_by_name():
|
||||||
assert module.get_configured_database(
|
assert module.get_configured_data_source(
|
||||||
config={
|
config={
|
||||||
'other_databases': [{'name': 'other'}],
|
'other_databases': [{'name': 'other'}],
|
||||||
'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}],
|
'postgresql_databases': [{'name': 'foo'}, {'name': 'bar'}],
|
||||||
},
|
},
|
||||||
archive_database_names={'postgresql_databases': ['other', 'foo', 'bar']},
|
archive_data_source_names={'postgresql_databases': ['other', 'foo', 'bar']},
|
||||||
hook_name=module.UNSPECIFIED_HOOK,
|
hook_name=module.UNSPECIFIED_HOOK,
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
) == ('postgresql_databases', {'name': 'bar'})
|
) == ('postgresql_databases', {'name': 'bar'})
|
||||||
|
|
||||||
|
|
||||||
def test_collect_archive_database_names_parses_archive_paths():
|
def test_collect_archive_data_source_names_parses_archive_paths():
|
||||||
flexmock(module.borgmatic.hooks.dump).should_receive('make_database_dump_path').and_return('')
|
flexmock(module.borgmatic.hooks.dump).should_receive('make_data_source_dump_path').and_return(
|
||||||
|
''
|
||||||
|
)
|
||||||
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
||||||
[
|
[
|
||||||
'.borgmatic/postgresql_databases/localhost/foo',
|
'.borgmatic/postgresql_databases/localhost/foo',
|
||||||
|
@ -75,7 +77,7 @@ def test_collect_archive_database_names_parses_archive_paths():
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
archive_database_names = module.collect_archive_database_names(
|
archive_data_source_names = module.collect_archive_data_source_names(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
archive='archive',
|
archive='archive',
|
||||||
config={'borgmatic_source_directory': '.borgmatic'},
|
config={'borgmatic_source_directory': '.borgmatic'},
|
||||||
|
@ -85,14 +87,16 @@ def test_collect_archive_database_names_parses_archive_paths():
|
||||||
remote_path=flexmock(),
|
remote_path=flexmock(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert archive_database_names == {
|
assert archive_data_source_names == {
|
||||||
'postgresql_databases': ['foo', 'bar'],
|
'postgresql_databases': ['foo', 'bar'],
|
||||||
'mysql_databases': ['quux'],
|
'mysql_databases': ['quux'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_collect_archive_database_names_parses_directory_format_archive_paths():
|
def test_collect_archive_data_source_names_parses_directory_format_archive_paths():
|
||||||
flexmock(module.borgmatic.hooks.dump).should_receive('make_database_dump_path').and_return('')
|
flexmock(module.borgmatic.hooks.dump).should_receive('make_data_source_dump_path').and_return(
|
||||||
|
''
|
||||||
|
)
|
||||||
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
||||||
[
|
[
|
||||||
'.borgmatic/postgresql_databases/localhost/foo/table1',
|
'.borgmatic/postgresql_databases/localhost/foo/table1',
|
||||||
|
@ -100,7 +104,7 @@ def test_collect_archive_database_names_parses_directory_format_archive_paths():
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
archive_database_names = module.collect_archive_database_names(
|
archive_data_source_names = module.collect_archive_data_source_names(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
archive='archive',
|
archive='archive',
|
||||||
config={'borgmatic_source_directory': '.borgmatic'},
|
config={'borgmatic_source_directory': '.borgmatic'},
|
||||||
|
@ -110,18 +114,20 @@ def test_collect_archive_database_names_parses_directory_format_archive_paths():
|
||||||
remote_path=flexmock(),
|
remote_path=flexmock(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert archive_database_names == {
|
assert archive_data_source_names == {
|
||||||
'postgresql_databases': ['foo'],
|
'postgresql_databases': ['foo'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_collect_archive_database_names_skips_bad_archive_paths():
|
def test_collect_archive_data_source_names_skips_bad_archive_paths():
|
||||||
flexmock(module.borgmatic.hooks.dump).should_receive('make_database_dump_path').and_return('')
|
flexmock(module.borgmatic.hooks.dump).should_receive('make_data_source_dump_path').and_return(
|
||||||
|
''
|
||||||
|
)
|
||||||
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
|
||||||
['.borgmatic/postgresql_databases/localhost/foo', '.borgmatic/invalid', 'invalid/as/well']
|
['.borgmatic/postgresql_databases/localhost/foo', '.borgmatic/invalid', 'invalid/as/well']
|
||||||
)
|
)
|
||||||
|
|
||||||
archive_database_names = module.collect_archive_database_names(
|
archive_data_source_names = module.collect_archive_data_source_names(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
archive='archive',
|
archive='archive',
|
||||||
config={'borgmatic_source_directory': '.borgmatic'},
|
config={'borgmatic_source_directory': '.borgmatic'},
|
||||||
|
@ -131,96 +137,96 @@ def test_collect_archive_database_names_skips_bad_archive_paths():
|
||||||
remote_path=flexmock(),
|
remote_path=flexmock(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert archive_database_names == {
|
assert archive_data_source_names == {
|
||||||
'postgresql_databases': ['foo'],
|
'postgresql_databases': ['foo'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_passes_through_requested_names_found_in_archive():
|
def test_find_data_sources_to_restore_passes_through_requested_names_found_in_archive():
|
||||||
restore_names = module.find_databases_to_restore(
|
restore_names = module.find_data_sources_to_restore(
|
||||||
requested_database_names=['foo', 'bar'],
|
requested_data_source_names=['foo', 'bar'],
|
||||||
archive_database_names={'postresql_databases': ['foo', 'bar', 'baz']},
|
archive_data_source_names={'postresql_databases': ['foo', 'bar', 'baz']},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert restore_names == {module.UNSPECIFIED_HOOK: ['foo', 'bar']}
|
assert restore_names == {module.UNSPECIFIED_HOOK: ['foo', 'bar']}
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_raises_for_requested_names_missing_from_archive():
|
def test_find_data_sources_to_restore_raises_for_requested_names_missing_from_archive():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.find_databases_to_restore(
|
module.find_data_sources_to_restore(
|
||||||
requested_database_names=['foo', 'bar'],
|
requested_data_source_names=['foo', 'bar'],
|
||||||
archive_database_names={'postresql_databases': ['foo']},
|
archive_data_source_names={'postresql_databases': ['foo']},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_without_requested_names_finds_all_archive_databases():
|
def test_find_data_sources_to_restore_without_requested_names_finds_all_archive_data_sources():
|
||||||
archive_database_names = {'postresql_databases': ['foo', 'bar']}
|
archive_data_source_names = {'postresql_databases': ['foo', 'bar']}
|
||||||
|
|
||||||
restore_names = module.find_databases_to_restore(
|
restore_names = module.find_data_sources_to_restore(
|
||||||
requested_database_names=[],
|
requested_data_source_names=[],
|
||||||
archive_database_names=archive_database_names,
|
archive_data_source_names=archive_data_source_names,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert restore_names == archive_database_names
|
assert restore_names == archive_data_source_names
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_with_all_in_requested_names_finds_all_archive_databases():
|
def test_find_data_sources_to_restore_with_all_in_requested_names_finds_all_archive_data_sources():
|
||||||
archive_database_names = {'postresql_databases': ['foo', 'bar']}
|
archive_data_source_names = {'postresql_databases': ['foo', 'bar']}
|
||||||
|
|
||||||
restore_names = module.find_databases_to_restore(
|
restore_names = module.find_data_sources_to_restore(
|
||||||
requested_database_names=['all'],
|
requested_data_source_names=['all'],
|
||||||
archive_database_names=archive_database_names,
|
archive_data_source_names=archive_data_source_names,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert restore_names == archive_database_names
|
assert restore_names == archive_data_source_names
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_with_all_in_requested_names_plus_additional_requested_names_omits_duplicates():
|
def test_find_data_sources_to_restore_with_all_in_requested_names_plus_additional_requested_names_omits_duplicates():
|
||||||
archive_database_names = {'postresql_databases': ['foo', 'bar']}
|
archive_data_source_names = {'postresql_databases': ['foo', 'bar']}
|
||||||
|
|
||||||
restore_names = module.find_databases_to_restore(
|
restore_names = module.find_data_sources_to_restore(
|
||||||
requested_database_names=['all', 'foo', 'bar'],
|
requested_data_source_names=['all', 'foo', 'bar'],
|
||||||
archive_database_names=archive_database_names,
|
archive_data_source_names=archive_data_source_names,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert restore_names == archive_database_names
|
assert restore_names == archive_data_source_names
|
||||||
|
|
||||||
|
|
||||||
def test_find_databases_to_restore_raises_for_all_in_requested_names_and_requested_named_missing_from_archives():
|
def test_find_data_sources_to_restore_raises_for_all_in_requested_names_and_requested_named_missing_from_archives():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.find_databases_to_restore(
|
module.find_data_sources_to_restore(
|
||||||
requested_database_names=['all', 'foo', 'bar'],
|
requested_data_source_names=['all', 'foo', 'bar'],
|
||||||
archive_database_names={'postresql_databases': ['foo']},
|
archive_data_source_names={'postresql_databases': ['foo']},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ensure_databases_found_with_all_databases_found_does_not_raise():
|
def test_ensure_data_sources_found_with_all_data_sources_found_does_not_raise():
|
||||||
module.ensure_databases_found(
|
module.ensure_data_sources_found(
|
||||||
restore_names={'postgresql_databases': ['foo']},
|
restore_names={'postgresql_databases': ['foo']},
|
||||||
remaining_restore_names={'postgresql_databases': ['bar']},
|
remaining_restore_names={'postgresql_databases': ['bar']},
|
||||||
found_names=['foo', 'bar'],
|
found_names=['foo', 'bar'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ensure_databases_found_with_no_databases_raises():
|
def test_ensure_data_sources_found_with_no_data_sources_raises():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.ensure_databases_found(
|
module.ensure_data_sources_found(
|
||||||
restore_names={'postgresql_databases': []},
|
restore_names={'postgresql_databases': []},
|
||||||
remaining_restore_names={},
|
remaining_restore_names={},
|
||||||
found_names=[],
|
found_names=[],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ensure_databases_found_with_missing_databases_raises():
|
def test_ensure_data_sources_found_with_missing_data_sources_raises():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.ensure_databases_found(
|
module.ensure_data_sources_found(
|
||||||
restore_names={'postgresql_databases': ['foo']},
|
restore_names={'postgresql_databases': ['foo']},
|
||||||
remaining_restore_names={'postgresql_databases': ['bar']},
|
remaining_restore_names={'postgresql_databases': ['bar']},
|
||||||
found_names=['foo'],
|
found_names=['foo'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_run_restore_restores_each_database():
|
def test_run_restore_restores_each_data_source():
|
||||||
restore_names = {
|
restore_names = {
|
||||||
'postgresql_databases': ['foo', 'bar'],
|
'postgresql_databases': ['foo', 'bar'],
|
||||||
}
|
}
|
||||||
|
@ -230,12 +236,12 @@ def test_run_restore_restores_each_database():
|
||||||
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
||||||
flexmock()
|
flexmock()
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('collect_archive_database_names').and_return(flexmock())
|
flexmock(module).should_receive('collect_archive_data_source_names').and_return(flexmock())
|
||||||
flexmock(module).should_receive('find_databases_to_restore').and_return(restore_names)
|
flexmock(module).should_receive('find_data_sources_to_restore').and_return(restore_names)
|
||||||
flexmock(module).should_receive('get_configured_database').and_return(
|
flexmock(module).should_receive('get_configured_data_source').and_return(
|
||||||
('postgresql_databases', {'name': 'foo'})
|
('postgresql_databases', {'name': 'foo'})
|
||||||
).and_return(('postgresql_databases', {'name': 'bar'}))
|
).and_return(('postgresql_databases', {'name': 'bar'}))
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -244,10 +250,10 @@ def test_run_restore_restores_each_database():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'foo', 'schemas': None},
|
data_source={'name': 'foo', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -256,10 +262,10 @@ def test_run_restore_restores_each_database():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'bar', 'schemas': None},
|
data_source={'name': 'bar', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('ensure_databases_found')
|
flexmock(module).should_receive('ensure_data_sources_found')
|
||||||
|
|
||||||
module.run_restore(
|
module.run_restore(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
|
@ -268,7 +274,7 @@ def test_run_restore_restores_each_database():
|
||||||
restore_arguments=flexmock(
|
restore_arguments=flexmock(
|
||||||
repository='repo',
|
repository='repo',
|
||||||
archive='archive',
|
archive='archive',
|
||||||
databases=flexmock(),
|
data_sources=flexmock(),
|
||||||
schemas=None,
|
schemas=None,
|
||||||
hostname=None,
|
hostname=None,
|
||||||
port=None,
|
port=None,
|
||||||
|
@ -289,20 +295,20 @@ def test_run_restore_bails_for_non_matching_repository():
|
||||||
flexmock(module.borgmatic.hooks.dispatch).should_receive(
|
flexmock(module.borgmatic.hooks.dispatch).should_receive(
|
||||||
'call_hooks_even_if_unconfigured'
|
'call_hooks_even_if_unconfigured'
|
||||||
).never()
|
).never()
|
||||||
flexmock(module).should_receive('restore_single_database').never()
|
flexmock(module).should_receive('restore_single_data_source').never()
|
||||||
|
|
||||||
module.run_restore(
|
module.run_restore(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
config=flexmock(),
|
config=flexmock(),
|
||||||
local_borg_version=flexmock(),
|
local_borg_version=flexmock(),
|
||||||
restore_arguments=flexmock(repository='repo', archive='archive', databases=flexmock()),
|
restore_arguments=flexmock(repository='repo', archive='archive', data_sources=flexmock()),
|
||||||
global_arguments=flexmock(dry_run=False),
|
global_arguments=flexmock(dry_run=False),
|
||||||
local_path=flexmock(),
|
local_path=flexmock(),
|
||||||
remote_path=flexmock(),
|
remote_path=flexmock(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_run_restore_restores_database_configured_with_all_name():
|
def test_run_restore_restores_data_source_configured_with_all_name():
|
||||||
restore_names = {
|
restore_names = {
|
||||||
'postgresql_databases': ['foo', 'bar'],
|
'postgresql_databases': ['foo', 'bar'],
|
||||||
}
|
}
|
||||||
|
@ -312,28 +318,28 @@ def test_run_restore_restores_database_configured_with_all_name():
|
||||||
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
||||||
flexmock()
|
flexmock()
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('collect_archive_database_names').and_return(flexmock())
|
flexmock(module).should_receive('collect_archive_data_source_names').and_return(flexmock())
|
||||||
flexmock(module).should_receive('find_databases_to_restore').and_return(restore_names)
|
flexmock(module).should_receive('find_data_sources_to_restore').and_return(restore_names)
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='foo',
|
data_source_name='foo',
|
||||||
).and_return(('postgresql_databases', {'name': 'foo'}))
|
).and_return(('postgresql_databases', {'name': 'foo'}))
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
).and_return((None, None))
|
).and_return((None, None))
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
configuration_database_name='all',
|
configuration_data_source_name='all',
|
||||||
).and_return(('postgresql_databases', {'name': 'bar'}))
|
).and_return(('postgresql_databases', {'name': 'bar'}))
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -342,10 +348,10 @@ def test_run_restore_restores_database_configured_with_all_name():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'foo', 'schemas': None},
|
data_source={'name': 'foo', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -354,10 +360,10 @@ def test_run_restore_restores_database_configured_with_all_name():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'bar', 'schemas': None},
|
data_source={'name': 'bar', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('ensure_databases_found')
|
flexmock(module).should_receive('ensure_data_sources_found')
|
||||||
|
|
||||||
module.run_restore(
|
module.run_restore(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
|
@ -366,7 +372,7 @@ def test_run_restore_restores_database_configured_with_all_name():
|
||||||
restore_arguments=flexmock(
|
restore_arguments=flexmock(
|
||||||
repository='repo',
|
repository='repo',
|
||||||
archive='archive',
|
archive='archive',
|
||||||
databases=flexmock(),
|
data_sources=flexmock(),
|
||||||
schemas=None,
|
schemas=None,
|
||||||
hostname=None,
|
hostname=None,
|
||||||
port=None,
|
port=None,
|
||||||
|
@ -380,7 +386,7 @@ def test_run_restore_restores_database_configured_with_all_name():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_run_restore_skips_missing_database():
|
def test_run_restore_skips_missing_data_source():
|
||||||
restore_names = {
|
restore_names = {
|
||||||
'postgresql_databases': ['foo', 'bar'],
|
'postgresql_databases': ['foo', 'bar'],
|
||||||
}
|
}
|
||||||
|
@ -390,28 +396,28 @@ def test_run_restore_skips_missing_database():
|
||||||
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
||||||
flexmock()
|
flexmock()
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('collect_archive_database_names').and_return(flexmock())
|
flexmock(module).should_receive('collect_archive_data_source_names').and_return(flexmock())
|
||||||
flexmock(module).should_receive('find_databases_to_restore').and_return(restore_names)
|
flexmock(module).should_receive('find_data_sources_to_restore').and_return(restore_names)
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='foo',
|
data_source_name='foo',
|
||||||
).and_return(('postgresql_databases', {'name': 'foo'}))
|
).and_return(('postgresql_databases', {'name': 'foo'}))
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
).and_return((None, None))
|
).and_return((None, None))
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
configuration_database_name='all',
|
configuration_data_source_name='all',
|
||||||
).and_return((None, None))
|
).and_return((None, None))
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -420,10 +426,10 @@ def test_run_restore_skips_missing_database():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'foo', 'schemas': None},
|
data_source={'name': 'foo', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -432,10 +438,10 @@ def test_run_restore_skips_missing_database():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'bar', 'schemas': None},
|
data_source={'name': 'bar', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).never()
|
).never()
|
||||||
flexmock(module).should_receive('ensure_databases_found')
|
flexmock(module).should_receive('ensure_data_sources_found')
|
||||||
|
|
||||||
module.run_restore(
|
module.run_restore(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
|
@ -444,7 +450,7 @@ def test_run_restore_skips_missing_database():
|
||||||
restore_arguments=flexmock(
|
restore_arguments=flexmock(
|
||||||
repository='repo',
|
repository='repo',
|
||||||
archive='archive',
|
archive='archive',
|
||||||
databases=flexmock(),
|
data_sources=flexmock(),
|
||||||
schemas=None,
|
schemas=None,
|
||||||
hostname=None,
|
hostname=None,
|
||||||
port=None,
|
port=None,
|
||||||
|
@ -458,7 +464,7 @@ def test_run_restore_skips_missing_database():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_run_restore_restores_databases_from_different_hooks():
|
def test_run_restore_restores_data_sources_from_different_hooks():
|
||||||
restore_names = {
|
restore_names = {
|
||||||
'postgresql_databases': ['foo'],
|
'postgresql_databases': ['foo'],
|
||||||
'mysql_databases': ['bar'],
|
'mysql_databases': ['bar'],
|
||||||
|
@ -469,21 +475,21 @@ def test_run_restore_restores_databases_from_different_hooks():
|
||||||
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
flexmock(module.borgmatic.borg.rlist).should_receive('resolve_archive_name').and_return(
|
||||||
flexmock()
|
flexmock()
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('collect_archive_database_names').and_return(flexmock())
|
flexmock(module).should_receive('collect_archive_data_source_names').and_return(flexmock())
|
||||||
flexmock(module).should_receive('find_databases_to_restore').and_return(restore_names)
|
flexmock(module).should_receive('find_data_sources_to_restore').and_return(restore_names)
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database_name='foo',
|
data_source_name='foo',
|
||||||
).and_return(('postgresql_databases', {'name': 'foo'}))
|
).and_return(('postgresql_databases', {'name': 'foo'}))
|
||||||
flexmock(module).should_receive('get_configured_database').with_args(
|
flexmock(module).should_receive('get_configured_data_source').with_args(
|
||||||
config=object,
|
config=object,
|
||||||
archive_database_names=object,
|
archive_data_source_names=object,
|
||||||
hook_name='mysql_databases',
|
hook_name='mysql_databases',
|
||||||
database_name='bar',
|
data_source_name='bar',
|
||||||
).and_return(('mysql_databases', {'name': 'bar'}))
|
).and_return(('mysql_databases', {'name': 'bar'}))
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -492,10 +498,10 @@ def test_run_restore_restores_databases_from_different_hooks():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='postgresql_databases',
|
hook_name='postgresql_databases',
|
||||||
database={'name': 'foo', 'schemas': None},
|
data_source={'name': 'foo', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('restore_single_database').with_args(
|
flexmock(module).should_receive('restore_single_data_source').with_args(
|
||||||
repository=object,
|
repository=object,
|
||||||
config=object,
|
config=object,
|
||||||
local_borg_version=object,
|
local_borg_version=object,
|
||||||
|
@ -504,10 +510,10 @@ def test_run_restore_restores_databases_from_different_hooks():
|
||||||
remote_path=object,
|
remote_path=object,
|
||||||
archive_name=object,
|
archive_name=object,
|
||||||
hook_name='mysql_databases',
|
hook_name='mysql_databases',
|
||||||
database={'name': 'bar', 'schemas': None},
|
data_source={'name': 'bar', 'schemas': None},
|
||||||
connection_params=object,
|
connection_params=object,
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('ensure_databases_found')
|
flexmock(module).should_receive('ensure_data_sources_found')
|
||||||
|
|
||||||
module.run_restore(
|
module.run_restore(
|
||||||
repository={'path': 'repo'},
|
repository={'path': 'repo'},
|
||||||
|
@ -516,7 +522,7 @@ def test_run_restore_restores_databases_from_different_hooks():
|
||||||
restore_arguments=flexmock(
|
restore_arguments=flexmock(
|
||||||
repository='repo',
|
repository='repo',
|
||||||
archive='archive',
|
archive='archive',
|
||||||
databases=flexmock(),
|
data_sources=flexmock(),
|
||||||
schemas=None,
|
schemas=None,
|
||||||
hostname=None,
|
hostname=None,
|
||||||
port=None,
|
port=None,
|
||||||
|
|
|
@ -4,34 +4,36 @@ from flexmock import flexmock
|
||||||
from borgmatic.hooks import dump as module
|
from borgmatic.hooks import dump as module
|
||||||
|
|
||||||
|
|
||||||
def test_make_database_dump_path_joins_arguments():
|
def test_make_data_source_dump_path_joins_arguments():
|
||||||
assert module.make_database_dump_path('/tmp', 'super_databases') == '/tmp/super_databases'
|
assert module.make_data_source_dump_path('/tmp', 'super_databases') == '/tmp/super_databases'
|
||||||
|
|
||||||
|
|
||||||
def test_make_database_dump_path_defaults_without_source_directory():
|
def test_make_data_source_dump_path_defaults_without_source_directory():
|
||||||
assert module.make_database_dump_path(None, 'super_databases') == '~/.borgmatic/super_databases'
|
assert (
|
||||||
|
module.make_data_source_dump_path(None, 'super_databases') == '~/.borgmatic/super_databases'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_make_database_dump_filename_uses_name_and_hostname():
|
def test_make_data_source_dump_filename_uses_name_and_hostname():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
module.make_database_dump_filename('databases', 'test', 'hostname')
|
module.make_data_source_dump_filename('databases', 'test', 'hostname')
|
||||||
== 'databases/hostname/test'
|
== 'databases/hostname/test'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_make_database_dump_filename_without_hostname_defaults_to_localhost():
|
def test_make_data_source_dump_filename_without_hostname_defaults_to_localhost():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
||||||
|
|
||||||
assert module.make_database_dump_filename('databases', 'test') == 'databases/localhost/test'
|
assert module.make_data_source_dump_filename('databases', 'test') == 'databases/localhost/test'
|
||||||
|
|
||||||
|
|
||||||
def test_make_database_dump_filename_with_invalid_name_raises():
|
def test_make_data_source_dump_filename_with_invalid_name_raises():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases')
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.make_database_dump_filename('databases', 'invalid/name')
|
module.make_data_source_dump_filename('databases', 'invalid/name')
|
||||||
|
|
||||||
|
|
||||||
def test_create_parent_directory_for_dump_does_not_raise():
|
def test_create_parent_directory_for_dump_does_not_raise():
|
||||||
|
@ -47,28 +49,28 @@ def test_create_named_pipe_for_dump_does_not_raise():
|
||||||
module.create_named_pipe_for_dump('/path/to/pipe')
|
module.create_named_pipe_for_dump('/path/to/pipe')
|
||||||
|
|
||||||
|
|
||||||
def test_remove_database_dumps_removes_dump_path():
|
def test_remove_data_source_dumps_removes_dump_path():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||||
flexmock(module.shutil).should_receive('rmtree').with_args('databases/localhost').once()
|
flexmock(module.shutil).should_receive('rmtree').with_args('databases/localhost').once()
|
||||||
|
|
||||||
module.remove_database_dumps('databases', 'SuperDB', 'test.yaml', dry_run=False)
|
module.remove_data_source_dumps('databases', 'SuperDB', 'test.yaml', dry_run=False)
|
||||||
|
|
||||||
|
|
||||||
def test_remove_database_dumps_with_dry_run_skips_removal():
|
def test_remove_data_source_dumps_with_dry_run_skips_removal():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
||||||
flexmock(module.os.path).should_receive('exists').never()
|
flexmock(module.os.path).should_receive('exists').never()
|
||||||
flexmock(module.shutil).should_receive('rmtree').never()
|
flexmock(module.shutil).should_receive('rmtree').never()
|
||||||
|
|
||||||
module.remove_database_dumps('databases', 'SuperDB', 'test.yaml', dry_run=True)
|
module.remove_data_source_dumps('databases', 'SuperDB', 'test.yaml', dry_run=True)
|
||||||
|
|
||||||
|
|
||||||
def test_remove_database_dumps_without_dump_path_present_skips_removal():
|
def test_remove_data_source_dumps_without_dump_path_present_skips_removal():
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
flexmock(module.os.path).should_receive('expanduser').and_return('databases/localhost')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.shutil).should_receive('rmtree').never()
|
flexmock(module.shutil).should_receive('rmtree').never()
|
||||||
|
|
||||||
module.remove_database_dumps('databases', 'SuperDB', 'test.yaml', dry_run=False)
|
module.remove_data_source_dumps('databases', 'SuperDB', 'test.yaml', dry_run=False)
|
||||||
|
|
||||||
|
|
||||||
def test_convert_glob_patterns_to_borg_patterns_removes_leading_slash():
|
def test_convert_glob_patterns_to_borg_patterns_removes_leading_slash():
|
||||||
|
|
|
@ -44,7 +44,7 @@ def test_database_names_to_dump_queries_mariadb_for_database_names():
|
||||||
assert names == ('foo', 'bar')
|
assert names == ('foo', 'bar')
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_each_database():
|
def test_dump_data_sources_dumps_each_database():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -63,10 +63,10 @@ def test_dump_databases_dumps_each_database():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_with_password():
|
def test_dump_data_sources_dumps_with_password():
|
||||||
database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'}
|
database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'}
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -84,10 +84,10 @@ def test_dump_databases_dumps_with_password():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases([database], {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources([database], {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_all_databases_at_once():
|
def test_dump_data_sources_dumps_all_databases_at_once():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -102,10 +102,10 @@ def test_dump_databases_dumps_all_databases_at_once():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_all_databases_separately_when_format_configured():
|
def test_dump_data_sources_dumps_all_databases_separately_when_format_configured():
|
||||||
databases = [{'name': 'all', 'format': 'sql'}]
|
databases = [{'name': 'all', 'format': 'sql'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -122,7 +122,7 @@ def test_dump_databases_dumps_all_databases_separately_when_format_configured():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_database_names_to_dump_runs_mariadb_with_list_options():
|
def test_database_names_to_dump_runs_mariadb_with_list_options():
|
||||||
|
@ -144,7 +144,7 @@ def test_database_names_to_dump_runs_mariadb_with_list_options():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mariadb_dump():
|
def test_execute_dump_command_runs_mariadb_dump():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ def test_execute_dump_command_runs_mariadb_dump():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
|
def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
|
def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
|
def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mariadb_dump_with_options():
|
def test_execute_dump_command_runs_mariadb_dump_with_options():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_options():
|
||||||
|
|
||||||
|
|
||||||
def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump():
|
def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump():
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
@ -336,7 +336,7 @@ def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump():
|
||||||
|
|
||||||
|
|
||||||
def test_execute_dump_command_with_dry_run_skips_mariadb_dump():
|
def test_execute_dump_command_with_dry_run_skips_mariadb_dump():
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -356,30 +356,30 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_errors_for_missing_all_databases():
|
def test_dump_data_sources_errors_for_missing_all_databases():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False)
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_does_not_error_for_missing_all_databases_with_dry_run():
|
def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mariadb_to_restore():
|
def test_restore_data_source_dump_runs_mariadb_to_restore():
|
||||||
hook_config = [{'name': 'foo'}, {'name': 'bar'}]
|
hook_config = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -391,11 +391,11 @@ def test_restore_database_dump_runs_mariadb_to_restore():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -407,7 +407,7 @@ def test_restore_database_dump_runs_mariadb_to_restore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mariadb_with_options():
|
def test_restore_data_source_dump_runs_mariadb_with_options():
|
||||||
hook_config = [{'name': 'foo', 'restore_options': '--harder'}]
|
hook_config = [{'name': 'foo', 'restore_options': '--harder'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -419,11 +419,11 @@ def test_restore_database_dump_runs_mariadb_with_options():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -435,7 +435,7 @@ def test_restore_database_dump_runs_mariadb_with_options():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mariadb_with_hostname_and_port():
|
def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port():
|
||||||
hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -456,11 +456,11 @@ def test_restore_database_dump_runs_mariadb_with_hostname_and_port():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -472,7 +472,7 @@ def test_restore_database_dump_runs_mariadb_with_hostname_and_port():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mariadb_with_username_and_password():
|
def test_restore_data_source_dump_runs_mariadb_with_username_and_password():
|
||||||
hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}]
|
hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -484,11 +484,11 @@ def test_restore_database_dump_runs_mariadb_with_username_and_password():
|
||||||
extra_environment={'MYSQL_PWD': 'trustsome1'},
|
extra_environment={'MYSQL_PWD': 'trustsome1'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -500,7 +500,7 @@ def test_restore_database_dump_runs_mariadb_with_username_and_password():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_connection_params_uses_connection_params_for_restore():
|
def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -533,11 +533,11 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
extra_environment={'MYSQL_PWD': 'clipassword'},
|
extra_environment={'MYSQL_PWD': 'clipassword'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -549,7 +549,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -584,11 +584,11 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
extra_environment={'MYSQL_PWD': 'restorepass'},
|
extra_environment={'MYSQL_PWD': 'restorepass'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -600,16 +600,16 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_dry_run_skips_restore():
|
def test_restore_data_source_dump_with_dry_run_skips_restore():
|
||||||
hook_config = [{'name': 'foo'}]
|
hook_config = [{'name': 'foo'}]
|
||||||
|
|
||||||
flexmock(module).should_receive('execute_command_with_processes').never()
|
flexmock(module).should_receive('execute_command_with_processes').never()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=True,
|
dry_run=True,
|
||||||
extract_process=flexmock(),
|
extract_process=flexmock(),
|
||||||
connection_params={
|
connection_params={
|
||||||
|
|
|
@ -5,11 +5,11 @@ from flexmock import flexmock
|
||||||
from borgmatic.hooks import mongodb as module
|
from borgmatic.hooks import mongodb as module
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodump_for_each_database():
|
def test_dump_data_sources_runs_mongodump_for_each_database():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
).and_return('databases/localhost/bar')
|
).and_return('databases/localhost/bar')
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
@ -21,26 +21,26 @@ def test_dump_databases_runs_mongodump_for_each_database():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_with_dry_run_skips_mongodump():
|
def test_dump_data_sources_with_dry_run_skips_mongodump():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
).and_return('databases/localhost/bar')
|
).and_return('databases/localhost/bar')
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodump_with_hostname_and_port():
|
def test_dump_data_sources_runs_mongodump_with_hostname_and_port():
|
||||||
databases = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
databases = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/database.example.org/foo'
|
'databases/database.example.org/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
@ -62,10 +62,10 @@ def test_dump_databases_runs_mongodump_with_hostname_and_port():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodump_with_username_and_password():
|
def test_dump_data_sources_runs_mongodump_with_username_and_password():
|
||||||
databases = [
|
databases = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -76,7 +76,7 @@ def test_dump_databases_runs_mongodump_with_username_and_password():
|
||||||
]
|
]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
@ -100,13 +100,13 @@ def test_dump_databases_runs_mongodump_with_username_and_password():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodump_with_directory_format():
|
def test_dump_data_sources_runs_mongodump_with_directory_format():
|
||||||
databases = [{'name': 'foo', 'format': 'directory'}]
|
databases = [{'name': 'foo', 'format': 'directory'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
||||||
|
@ -117,14 +117,14 @@ def test_dump_databases_runs_mongodump_with_directory_format():
|
||||||
shell=True,
|
shell=True,
|
||||||
).and_return(flexmock()).once()
|
).and_return(flexmock()).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodump_with_options():
|
def test_dump_data_sources_runs_mongodump_with_options():
|
||||||
databases = [{'name': 'foo', 'options': '--stuff=such'}]
|
databases = [{'name': 'foo', 'options': '--stuff=such'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
@ -143,14 +143,14 @@ def test_dump_databases_runs_mongodump_with_options():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_mongodumpall_for_all_databases():
|
def test_dump_data_sources_runs_mongodumpall_for_all_databases():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
@ -161,15 +161,15 @@ def test_dump_databases_runs_mongodumpall_for_all_databases():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mongorestore():
|
def test_restore_data_source_dump_runs_mongorestore():
|
||||||
hook_config = [{'name': 'foo', 'schemas': None}, {'name': 'bar'}]
|
hook_config = [{'name': 'foo', 'schemas': None}, {'name': 'bar'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
['mongorestore', '--archive', '--drop'],
|
['mongorestore', '--archive', '--drop'],
|
||||||
processes=[extract_process],
|
processes=[extract_process],
|
||||||
|
@ -177,11 +177,11 @@ def test_restore_database_dump_runs_mongorestore():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -193,14 +193,14 @@ def test_restore_database_dump_runs_mongorestore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mongorestore_with_hostname_and_port():
|
def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}
|
{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}
|
||||||
]
|
]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
[
|
[
|
||||||
'mongorestore',
|
'mongorestore',
|
||||||
|
@ -216,11 +216,11 @@ def test_restore_database_dump_runs_mongorestore_with_hostname_and_port():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -232,7 +232,7 @@ def test_restore_database_dump_runs_mongorestore_with_hostname_and_port():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mongorestore_with_username_and_password():
|
def test_restore_data_source_dump_runs_mongorestore_with_username_and_password():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -245,7 +245,7 @@ def test_restore_database_dump_runs_mongorestore_with_username_and_password():
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
[
|
[
|
||||||
'mongorestore',
|
'mongorestore',
|
||||||
|
@ -263,11 +263,11 @@ def test_restore_database_dump_runs_mongorestore_with_username_and_password():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -279,7 +279,7 @@ def test_restore_database_dump_runs_mongorestore_with_username_and_password():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_connection_params_uses_connection_params_for_restore():
|
def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -296,7 +296,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
[
|
[
|
||||||
'mongorestore',
|
'mongorestore',
|
||||||
|
@ -318,11 +318,11 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -334,7 +334,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -351,7 +351,7 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
[
|
[
|
||||||
'mongorestore',
|
'mongorestore',
|
||||||
|
@ -373,11 +373,11 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -389,12 +389,12 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mongorestore_with_options():
|
def test_restore_data_source_dump_runs_mongorestore_with_options():
|
||||||
hook_config = [{'name': 'foo', 'restore_options': '--harder', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'restore_options': '--harder', 'schemas': None}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
['mongorestore', '--archive', '--drop', '--harder'],
|
['mongorestore', '--archive', '--drop', '--harder'],
|
||||||
processes=[extract_process],
|
processes=[extract_process],
|
||||||
|
@ -402,11 +402,11 @@ def test_restore_database_dump_runs_mongorestore_with_options():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -423,7 +423,7 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
[
|
[
|
||||||
'mongorestore',
|
'mongorestore',
|
||||||
|
@ -439,11 +439,11 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -455,12 +455,12 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_psql_for_all_database_dump():
|
def test_restore_data_source_dump_runs_psql_for_all_database_dump():
|
||||||
hook_config = [{'name': 'all', 'schemas': None}]
|
hook_config = [{'name': 'all', 'schemas': None}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
['mongorestore', '--archive'],
|
['mongorestore', '--archive'],
|
||||||
processes=[extract_process],
|
processes=[extract_process],
|
||||||
|
@ -468,11 +468,11 @@ def test_restore_database_dump_runs_psql_for_all_database_dump():
|
||||||
input_file=extract_process.stdout,
|
input_file=extract_process.stdout,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -484,18 +484,18 @@ def test_restore_database_dump_runs_psql_for_all_database_dump():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_dry_run_skips_restore():
|
def test_restore_data_source_dump_with_dry_run_skips_restore():
|
||||||
hook_config = [{'name': 'foo', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'schemas': None}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').never()
|
flexmock(module).should_receive('execute_command_with_processes').never()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=True,
|
dry_run=True,
|
||||||
extract_process=flexmock(),
|
extract_process=flexmock(),
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -507,11 +507,11 @@ def test_restore_database_dump_with_dry_run_skips_restore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_extract_process_restores_from_disk():
|
def test_restore_data_source_dump_without_extract_process_restores_from_disk():
|
||||||
hook_config = [{'name': 'foo', 'format': 'directory', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'format': 'directory', 'schemas': None}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('/dump/path')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
['mongorestore', '--dir', '/dump/path', '--drop'],
|
['mongorestore', '--dir', '/dump/path', '--drop'],
|
||||||
processes=[],
|
processes=[],
|
||||||
|
@ -519,11 +519,11 @@ def test_restore_database_dump_without_extract_process_restores_from_disk():
|
||||||
input_file=None,
|
input_file=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=None,
|
extract_process=None,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
|
|
@ -44,7 +44,7 @@ def test_database_names_to_dump_queries_mysql_for_database_names():
|
||||||
assert names == ('foo', 'bar')
|
assert names == ('foo', 'bar')
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_each_database():
|
def test_dump_data_sources_dumps_each_database():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -63,10 +63,10 @@ def test_dump_databases_dumps_each_database():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_with_password():
|
def test_dump_data_sources_dumps_with_password():
|
||||||
database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'}
|
database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'}
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -84,10 +84,10 @@ def test_dump_databases_dumps_with_password():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases([database], {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources([database], {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_all_databases_at_once():
|
def test_dump_data_sources_dumps_all_databases_at_once():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -102,10 +102,10 @@ def test_dump_databases_dumps_all_databases_at_once():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_all_databases_separately_when_format_configured():
|
def test_dump_data_sources_dumps_all_databases_separately_when_format_configured():
|
||||||
databases = [{'name': 'all', 'format': 'sql'}]
|
databases = [{'name': 'all', 'format': 'sql'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
|
@ -122,7 +122,7 @@ def test_dump_databases_dumps_all_databases_separately_when_format_configured():
|
||||||
dry_run_label=object,
|
dry_run_label=object,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_database_names_to_dump_runs_mysql_with_list_options():
|
def test_database_names_to_dump_runs_mysql_with_list_options():
|
||||||
|
@ -144,7 +144,7 @@ def test_database_names_to_dump_runs_mysql_with_list_options():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mysqldump():
|
def test_execute_dump_command_runs_mysqldump():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ def test_execute_dump_command_runs_mysqldump():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
|
def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
|
def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mysqldump_with_username_and_password():
|
def test_execute_dump_command_runs_mysqldump_with_username_and_password():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password():
|
||||||
|
|
||||||
def test_execute_dump_command_runs_mysqldump_with_options():
|
def test_execute_dump_command_runs_mysqldump_with_options():
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ def test_execute_dump_command_runs_mysqldump_with_options():
|
||||||
|
|
||||||
|
|
||||||
def test_execute_dump_command_with_duplicate_dump_skips_mysqldump():
|
def test_execute_dump_command_with_duplicate_dump_skips_mysqldump():
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
@ -336,7 +336,7 @@ def test_execute_dump_command_with_duplicate_dump_skips_mysqldump():
|
||||||
|
|
||||||
|
|
||||||
def test_execute_dump_command_with_dry_run_skips_mysqldump():
|
def test_execute_dump_command_with_dry_run_skips_mysqldump():
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('dump')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump')
|
||||||
|
|
||||||
|
@ -356,30 +356,30 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_errors_for_missing_all_databases():
|
def test_dump_data_sources_errors_for_missing_all_databases():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False)
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_does_not_error_for_missing_all_databases_with_dry_run():
|
def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mysql_to_restore():
|
def test_restore_data_source_dump_runs_mysql_to_restore():
|
||||||
hook_config = [{'name': 'foo'}, {'name': 'bar'}]
|
hook_config = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -391,11 +391,11 @@ def test_restore_database_dump_runs_mysql_to_restore():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -407,7 +407,7 @@ def test_restore_database_dump_runs_mysql_to_restore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mysql_with_options():
|
def test_restore_data_source_dump_runs_mysql_with_options():
|
||||||
hook_config = [{'name': 'foo', 'restore_options': '--harder'}]
|
hook_config = [{'name': 'foo', 'restore_options': '--harder'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -419,11 +419,11 @@ def test_restore_database_dump_runs_mysql_with_options():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -435,7 +435,7 @@ def test_restore_database_dump_runs_mysql_with_options():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mysql_with_hostname_and_port():
|
def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
|
||||||
hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -456,11 +456,11 @@ def test_restore_database_dump_runs_mysql_with_hostname_and_port():
|
||||||
extra_environment=None,
|
extra_environment=None,
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -472,7 +472,7 @@ def test_restore_database_dump_runs_mysql_with_hostname_and_port():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_mysql_with_username_and_password():
|
def test_restore_data_source_dump_runs_mysql_with_username_and_password():
|
||||||
hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}]
|
hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -484,11 +484,11 @@ def test_restore_database_dump_runs_mysql_with_username_and_password():
|
||||||
extra_environment={'MYSQL_PWD': 'trustsome1'},
|
extra_environment={'MYSQL_PWD': 'trustsome1'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -500,7 +500,7 @@ def test_restore_database_dump_runs_mysql_with_username_and_password():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_connection_params_uses_connection_params_for_restore():
|
def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -533,11 +533,11 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
extra_environment={'MYSQL_PWD': 'clipassword'},
|
extra_environment={'MYSQL_PWD': 'clipassword'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -549,7 +549,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -584,11 +584,11 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
extra_environment={'MYSQL_PWD': 'restorepass'},
|
extra_environment={'MYSQL_PWD': 'restorepass'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -600,16 +600,16 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_dry_run_skips_restore():
|
def test_restore_data_source_dump_with_dry_run_skips_restore():
|
||||||
hook_config = [{'name': 'foo'}]
|
hook_config = [{'name': 'foo'}]
|
||||||
|
|
||||||
flexmock(module).should_receive('execute_command_with_processes').never()
|
flexmock(module).should_receive('execute_command_with_processes').never()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=True,
|
dry_run=True,
|
||||||
extract_process=flexmock(),
|
extract_process=flexmock(),
|
||||||
connection_params={
|
connection_params={
|
||||||
|
|
|
@ -185,7 +185,7 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dump_for_each_database():
|
def test_dump_data_sources_runs_pg_dump_for_each_database():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
|
@ -193,7 +193,7 @@ def test_dump_databases_runs_pg_dump_for_each_database():
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
||||||
('bar',)
|
('bar',)
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
).and_return('databases/localhost/bar')
|
).and_return('databases/localhost/bar')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -217,69 +217,69 @@ def test_dump_databases_runs_pg_dump_for_each_database():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_raises_when_no_database_names_to_dump():
|
def test_dump_data_sources_raises_when_no_database_names_to_dump():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.dump_databases(databases, {}, 'test.yaml', dry_run=False)
|
module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False)
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_does_not_raise_when_no_database_names_to_dump():
|
def test_dump_data_sources_does_not_raise_when_no_database_names_to_dump():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
flexmock(module).should_receive('database_names_to_dump').and_return(())
|
||||||
|
|
||||||
module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_with_duplicate_dump_skips_pg_dump():
|
def test_dump_data_sources_with_duplicate_dump_skips_pg_dump():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
||||||
('bar',)
|
('bar',)
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
).and_return('databases/localhost/bar')
|
).and_return('databases/localhost/bar')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_with_dry_run_skips_pg_dump():
|
def test_dump_data_sources_with_dry_run_skips_pg_dump():
|
||||||
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
databases = [{'name': 'foo'}, {'name': 'bar'}]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
|
||||||
('bar',)
|
('bar',)
|
||||||
)
|
)
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
).and_return('databases/localhost/bar')
|
).and_return('databases/localhost/bar')
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dump_with_hostname_and_port():
|
def test_dump_data_sources_runs_pg_dump_with_hostname_and_port():
|
||||||
databases = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
databases = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/database.example.org/foo'
|
'databases/database.example.org/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -306,10 +306,10 @@ def test_dump_databases_runs_pg_dump_with_hostname_and_port():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dump_with_username_and_password():
|
def test_dump_data_sources_runs_pg_dump_with_username_and_password():
|
||||||
databases = [{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1'}]
|
databases = [{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return(
|
flexmock(module).should_receive('make_extra_environment').and_return(
|
||||||
|
@ -317,7 +317,7 @@ def test_dump_databases_runs_pg_dump_with_username_and_password():
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -342,15 +342,15 @@ def test_dump_databases_runs_pg_dump_with_username_and_password():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dump_with_directory_format():
|
def test_dump_data_sources_runs_pg_dump_with_directory_format():
|
||||||
databases = [{'name': 'foo', 'format': 'directory'}]
|
databases = [{'name': 'foo', 'format': 'directory'}]
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -373,16 +373,16 @@ def test_dump_databases_runs_pg_dump_with_directory_format():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).and_return(flexmock()).once()
|
).and_return(flexmock()).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dump_with_options():
|
def test_dump_data_sources_runs_pg_dump_with_options():
|
||||||
databases = [{'name': 'foo', 'options': '--stuff=such'}]
|
databases = [{'name': 'foo', 'options': '--stuff=such'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -406,16 +406,16 @@ def test_dump_databases_runs_pg_dump_with_options():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_pg_dumpall_for_all_databases():
|
def test_dump_data_sources_runs_pg_dumpall_for_all_databases():
|
||||||
databases = [{'name': 'all'}]
|
databases = [{'name': 'all'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('all',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('all',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/all'
|
'databases/localhost/all'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -428,16 +428,16 @@ def test_dump_databases_runs_pg_dumpall_for_all_databases():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_runs_non_default_pg_dump():
|
def test_dump_data_sources_runs_non_default_pg_dump():
|
||||||
databases = [{'name': 'foo', 'pg_dump_command': 'special_pg_dump'}]
|
databases = [{'name': 'foo', 'pg_dump_command': 'special_pg_dump'}]
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('')
|
flexmock(module).should_receive('make_dump_path').and_return('')
|
||||||
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
flexmock(module).should_receive('database_names_to_dump').and_return(('foo',))
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'databases/localhost/foo'
|
'databases/localhost/foo'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -460,16 +460,16 @@ def test_dump_databases_runs_non_default_pg_dump():
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == [process]
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == [process]
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_pg_restore():
|
def test_restore_data_source_dump_runs_pg_restore():
|
||||||
hook_config = [{'name': 'foo', 'schemas': None}, {'name': 'bar'}]
|
hook_config = [{'name': 'foo', 'schemas': None}, {'name': 'bar'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -499,11 +499,11 @@ def test_restore_database_dump_runs_pg_restore():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -515,7 +515,7 @@ def test_restore_database_dump_runs_pg_restore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_pg_restore_with_hostname_and_port():
|
def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}
|
{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433, 'schemas': None}
|
||||||
]
|
]
|
||||||
|
@ -523,7 +523,7 @@ def test_restore_database_dump_runs_pg_restore_with_hostname_and_port():
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -561,11 +561,11 @@ def test_restore_database_dump_runs_pg_restore_with_hostname_and_port():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -577,7 +577,7 @@ def test_restore_database_dump_runs_pg_restore_with_hostname_and_port():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_pg_restore_with_username_and_password():
|
def test_restore_data_source_dump_runs_pg_restore_with_username_and_password():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1', 'schemas': None}
|
{'name': 'foo', 'username': 'postgres', 'password': 'trustsome1', 'schemas': None}
|
||||||
]
|
]
|
||||||
|
@ -587,7 +587,7 @@ def test_restore_database_dump_runs_pg_restore_with_username_and_password():
|
||||||
{'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}
|
{'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'}
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -621,11 +621,11 @@ def test_restore_database_dump_runs_pg_restore_with_username_and_password():
|
||||||
extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
|
extra_environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -637,7 +637,7 @@ def test_restore_database_dump_runs_pg_restore_with_username_and_password():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_connection_params_uses_connection_params_for_restore():
|
def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -658,7 +658,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
{'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}
|
{'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'}
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -700,11 +700,11 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
extra_environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'},
|
extra_environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -716,7 +716,7 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -737,7 +737,7 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
{'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}
|
{'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'}
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -779,11 +779,11 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
extra_environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'},
|
extra_environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -795,7 +795,7 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_pg_restore_with_options():
|
def test_restore_data_source_dump_runs_pg_restore_with_options():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -808,7 +808,7 @@ def test_restore_database_dump_runs_pg_restore_with_options():
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -840,11 +840,11 @@ def test_restore_database_dump_runs_pg_restore_with_options():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -856,13 +856,13 @@ def test_restore_database_dump_runs_pg_restore_with_options():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_psql_for_all_database_dump():
|
def test_restore_data_source_dump_runs_psql_for_all_database_dump():
|
||||||
hook_config = [{'name': 'all', 'schemas': None}]
|
hook_config = [{'name': 'all', 'schemas': None}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'psql',
|
'psql',
|
||||||
|
@ -879,11 +879,11 @@ def test_restore_database_dump_runs_psql_for_all_database_dump():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'all'},
|
data_source={'name': 'all'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -895,13 +895,13 @@ def test_restore_database_dump_runs_psql_for_all_database_dump():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_psql_for_plain_database_dump():
|
def test_restore_data_source_dump_runs_psql_for_plain_database_dump():
|
||||||
hook_config = [{'name': 'foo', 'format': 'plain', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'format': 'plain', 'schemas': None}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
('psql', '--no-password', '--no-psqlrc', '--dbname', 'foo'),
|
('psql', '--no-password', '--no-psqlrc', '--dbname', 'foo'),
|
||||||
processes=[extract_process],
|
processes=[extract_process],
|
||||||
|
@ -923,11 +923,11 @@ def test_restore_database_dump_runs_psql_for_plain_database_dump():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -939,7 +939,7 @@ def test_restore_database_dump_runs_psql_for_plain_database_dump():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_runs_non_default_pg_restore_and_psql():
|
def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{
|
{
|
||||||
'name': 'foo',
|
'name': 'foo',
|
||||||
|
@ -952,7 +952,7 @@ def test_restore_database_dump_runs_non_default_pg_restore_and_psql():
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'docker',
|
'docker',
|
||||||
|
@ -988,11 +988,11 @@ def test_restore_database_dump_runs_non_default_pg_restore_and_psql():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -1004,19 +1004,19 @@ def test_restore_database_dump_runs_non_default_pg_restore_and_psql():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_dry_run_skips_restore():
|
def test_restore_data_source_dump_with_dry_run_skips_restore():
|
||||||
hook_config = [{'name': 'foo', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'schemas': None}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').never()
|
flexmock(module).should_receive('execute_command_with_processes').never()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=True,
|
dry_run=True,
|
||||||
extract_process=flexmock(),
|
extract_process=flexmock(),
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -1028,12 +1028,12 @@ def test_restore_database_dump_with_dry_run_skips_restore():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_extract_process_restores_from_disk():
|
def test_restore_data_source_dump_without_extract_process_restores_from_disk():
|
||||||
hook_config = [{'name': 'foo', 'schemas': None}]
|
hook_config = [{'name': 'foo', 'schemas': None}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('/dump/path')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -1064,11 +1064,11 @@ def test_restore_database_dump_without_extract_process_restores_from_disk():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'foo'},
|
data_source={'name': 'foo'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=None,
|
extract_process=None,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
@ -1080,12 +1080,12 @@ def test_restore_database_dump_without_extract_process_restores_from_disk():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_schemas_restores_schemas():
|
def test_restore_data_source_dump_with_schemas_restores_schemas():
|
||||||
hook_config = [{'name': 'foo', 'schemas': ['bar', 'baz']}]
|
hook_config = [{'name': 'foo', 'schemas': ['bar', 'baz']}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'})
|
||||||
flexmock(module).should_receive('make_dump_path')
|
flexmock(module).should_receive('make_dump_path')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return('/dump/path')
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path')
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
(
|
(
|
||||||
'pg_restore',
|
'pg_restore',
|
||||||
|
@ -1120,11 +1120,11 @@ def test_restore_database_dump_with_schemas_restores_schemas():
|
||||||
extra_environment={'PGSSLMODE': 'disable'},
|
extra_environment={'PGSSLMODE': 'disable'},
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=None,
|
extract_process=None,
|
||||||
connection_params={
|
connection_params={
|
||||||
|
|
|
@ -5,21 +5,21 @@ from flexmock import flexmock
|
||||||
from borgmatic.hooks import sqlite as module
|
from borgmatic.hooks import sqlite as module
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_logs_and_skips_if_dump_already_exists():
|
def test_dump_data_sources_logs_and_skips_if_dump_already_exists():
|
||||||
databases = [{'path': '/path/to/database', 'name': 'database'}]
|
databases = [{'path': '/path/to/database', 'name': 'database'}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'/path/to/dump/database'
|
'/path/to/dump/database'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(True)
|
flexmock(module.os.path).should_receive('exists').and_return(True)
|
||||||
flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
|
flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == []
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_dumps_each_database():
|
def test_dump_data_sources_dumps_each_database():
|
||||||
databases = [
|
databases = [
|
||||||
{'path': '/path/to/database1', 'name': 'database1'},
|
{'path': '/path/to/database1', 'name': 'database1'},
|
||||||
{'path': '/path/to/database2', 'name': 'database2'},
|
{'path': '/path/to/database2', 'name': 'database2'},
|
||||||
|
@ -27,7 +27,7 @@ def test_dump_databases_dumps_each_database():
|
||||||
processes = [flexmock(), flexmock()]
|
processes = [flexmock(), flexmock()]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'/path/to/dump/database'
|
'/path/to/dump/database'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
|
@ -36,7 +36,7 @@ def test_dump_databases_dumps_each_database():
|
||||||
processes[1]
|
processes[1]
|
||||||
)
|
)
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dumping_database_with_non_existent_path_warns_and_dumps_database():
|
def test_dumping_database_with_non_existent_path_warns_and_dumps_database():
|
||||||
|
@ -47,14 +47,14 @@ def test_dumping_database_with_non_existent_path_warns_and_dumps_database():
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
flexmock(module.logger).should_receive('warning').once()
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'/path/to/dump/database'
|
'/path/to/dump/database'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
||||||
flexmock(module).should_receive('execute_command').and_return(processes[0])
|
flexmock(module).should_receive('execute_command').and_return(processes[0])
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dumping_database_with_name_all_warns_and_dumps_all_databases():
|
def test_dumping_database_with_name_all_warns_and_dumps_all_databases():
|
||||||
|
@ -67,31 +67,31 @@ def test_dumping_database_with_name_all_warns_and_dumps_all_databases():
|
||||||
flexmock(module.logger).should_receive(
|
flexmock(module.logger).should_receive(
|
||||||
'warning'
|
'warning'
|
||||||
).twice() # once for the name=all, once for the non-existent path
|
).twice() # once for the name=all, once for the non-existent path
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'/path/to/dump/database'
|
'/path/to/dump/database'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
flexmock(module.dump).should_receive('create_parent_directory_for_dump')
|
||||||
flexmock(module).should_receive('execute_command').and_return(processes[0])
|
flexmock(module).should_receive('execute_command').and_return(processes[0])
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=False) == processes
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
|
||||||
|
|
||||||
|
|
||||||
def test_dump_databases_does_not_dump_if_dry_run():
|
def test_dump_data_sources_does_not_dump_if_dry_run():
|
||||||
databases = [{'path': '/path/to/database', 'name': 'database'}]
|
databases = [{'path': '/path/to/database', 'name': 'database'}]
|
||||||
|
|
||||||
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
|
||||||
flexmock(module.dump).should_receive('make_database_dump_filename').and_return(
|
flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
|
||||||
'/path/to/dump/database'
|
'/path/to/dump/database'
|
||||||
)
|
)
|
||||||
flexmock(module.os.path).should_receive('exists').and_return(False)
|
flexmock(module.os.path).should_receive('exists').and_return(False)
|
||||||
flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
|
flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
|
|
||||||
assert module.dump_databases(databases, {}, 'test.yaml', dry_run=True) == []
|
assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_restores_database():
|
def test_restore_data_source_dump_restores_database():
|
||||||
hook_config = [{'path': '/path/to/database', 'name': 'database'}, {'name': 'other'}]
|
hook_config = [{'path': '/path/to/database', 'name': 'database'}, {'name': 'other'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
|
@ -107,18 +107,18 @@ def test_restore_database_dump_restores_database():
|
||||||
|
|
||||||
flexmock(module.os).should_receive('remove').once()
|
flexmock(module.os).should_receive('remove').once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={'restore_path': None},
|
connection_params={'restore_path': None},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_with_connection_params_uses_connection_params_for_restore():
|
def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
|
{'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
|
||||||
]
|
]
|
||||||
|
@ -136,18 +136,18 @@ def test_restore_database_dump_with_connection_params_uses_connection_params_for
|
||||||
|
|
||||||
flexmock(module.os).should_receive('remove').once()
|
flexmock(module.os).should_receive('remove').once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'database'},
|
data_source={'name': 'database'},
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={'restore_path': 'cli/path/to/database'},
|
connection_params={'restore_path': 'cli/path/to/database'},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
|
||||||
hook_config = [
|
hook_config = [
|
||||||
{'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
|
{'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
|
||||||
]
|
]
|
||||||
|
@ -165,29 +165,29 @@ def test_restore_database_dump_without_connection_params_uses_restore_params_in_
|
||||||
|
|
||||||
flexmock(module.os).should_receive('remove').once()
|
flexmock(module.os).should_receive('remove').once()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database=hook_config[0],
|
data_source=hook_config[0],
|
||||||
dry_run=False,
|
dry_run=False,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={'restore_path': None},
|
connection_params={'restore_path': None},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_restore_database_dump_does_not_restore_database_if_dry_run():
|
def test_restore_data_source_dump_does_not_restore_database_if_dry_run():
|
||||||
hook_config = [{'path': '/path/to/database', 'name': 'database'}]
|
hook_config = [{'path': '/path/to/database', 'name': 'database'}]
|
||||||
extract_process = flexmock(stdout=flexmock())
|
extract_process = flexmock(stdout=flexmock())
|
||||||
|
|
||||||
flexmock(module).should_receive('execute_command_with_processes').never()
|
flexmock(module).should_receive('execute_command_with_processes').never()
|
||||||
flexmock(module.os).should_receive('remove').never()
|
flexmock(module.os).should_receive('remove').never()
|
||||||
|
|
||||||
module.restore_database_dump(
|
module.restore_data_source_dump(
|
||||||
hook_config,
|
hook_config,
|
||||||
{},
|
{},
|
||||||
'test.yaml',
|
'test.yaml',
|
||||||
database={'name': 'database'},
|
data_source={'name': 'database'},
|
||||||
dry_run=True,
|
dry_run=True,
|
||||||
extract_process=extract_process,
|
extract_process=extract_process,
|
||||||
connection_params={'restore_path': None},
|
connection_params={'restore_path': None},
|
||||||
|
|
Loading…
Reference in a new issue