fixes and more tests.

This commit is contained in:
Florian Apolloner
2025-09-15 20:02:31 +02:00
parent db1c6f548f
commit 04cc58a5c7
4 changed files with 108 additions and 4 deletions
+14 -2
View File
@@ -176,7 +176,13 @@ def restore_single_dump(
that data source from the archive.
'''
dump_metadata = render_dump_metadata(
Dump(hook_name, data_source['name'], data_source.get('hostname'), data_source.get('port'), data_source.get('label')),
Dump(
hook_name,
data_source['name'],
data_source.get('hostname'),
data_source.get('port'),
data_source.get('label'),
),
)
logger.info(f'Restoring data source {dump_metadata}')
@@ -568,7 +574,13 @@ def run_restore(
if not found_data_source:
found_data_source = get_configured_data_source(
config,
Dump(restore_dump.hook_name, 'all', restore_dump.hostname, restore_dump.port, restore_dump.label),
Dump(
restore_dump.hook_name,
'all',
restore_dump.hostname,
restore_dump.port,
restore_dump.label,
),
)
if not found_data_source:
+2 -1
View File
@@ -9,6 +9,7 @@ IS_A_HOOK = False
logger = logging.getLogger(__name__)
def resolve_database_option(option, data_source, connection_params=None, restore=False):
# Special case `hostname` since it overlaps with `container`
if option == 'hostname':
@@ -24,7 +25,7 @@ def _get_hostname_from_config(data_source, connection_params=None, restore=False
# connection params win, full stop
if connection_params:
if container := connection_params.get('container'):
return container
return get_ip_from_container(container)
if hostname := connection_params.get('hostname'):
return hostname
# ... then try the restore config
+1 -1
View File
@@ -1102,7 +1102,7 @@ def test_run_restore_restores_each_data_source():
username=None,
password=None,
restore_path=None,
container=None
container=None,
),
global_arguments=flexmock(dry_run=False),
local_path=flexmock(),
@@ -0,0 +1,91 @@
from subprocess import CalledProcessError
import pytest
from flexmock import flexmock
from borgmatic.hooks.data_source import utils
def test_get_database_option():
data_source = {'option': 'original_value', 'restore_option': 'restore_value'}
connection_params = {'option': 'connection_value'}
assert utils.resolve_database_option('option', data_source) == 'original_value'
assert utils.resolve_database_option('option', data_source, restore=True) == 'restore_value'
assert (
utils.resolve_database_option('option', data_source, connection_params)
== 'connection_value'
)
assert (
utils.resolve_database_option('option', data_source, connection_params, restore=True)
== 'connection_value'
)
def test_get_hostname_option_via_container():
data_source = {
'container': 'original_container',
'hostname': 'original_hostname',
'restore_container': 'restore_container',
'restore_hostname': 'restore_hostname',
}
connection_params = {'container': 'connection_container', 'hostname': 'connection_hostname'}
flexmock(utils).should_receive('get_ip_from_container').with_args(
'original_container'
).and_return('container_ip_1')
flexmock(utils).should_receive('get_ip_from_container').with_args(
'connection_container'
).and_return('container_ip_2')
flexmock(utils).should_receive('get_ip_from_container').with_args(
'restore_container'
).and_return('container_ip_3')
assert utils.resolve_database_option('hostname', data_source) == 'container_ip_1'
assert (
utils.resolve_database_option('hostname', data_source, connection_params)
== 'container_ip_2'
)
assert utils.resolve_database_option('hostname', data_source, restore=True) == 'container_ip_3'
def test_get_container_ip_without_engines():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return(None)
with pytest.raises(ValueError):
utils.get_ip_from_container('yolo')
def test_get_container_ip_success():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_return(
'{"IPAddress": "1.2.3.4"}'
)
addr = utils.get_ip_from_container('yolo')
assert addr == '1.2.3.4'
flexmock(utils).should_receive('execute_command_and_capture_output').and_return(
'{"Networks": {"my_network": {"IPAddress": "5.6.7.8"}}}'
)
assert utils.get_ip_from_container('yolo') == '5.6.7.8'
def test_get_container_ip_container_not_found():
flexmock(utils.shutil).should_receive('which').and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_raise(
CalledProcessError, 1, ['/usr/bin/podman', 'inspect', 'yolo'], None, 'No such object'
)
with pytest.raises(CalledProcessError):
utils.get_ip_from_container('does not exist')
def test_get_container_ip_container_no_network():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_return('{}')
assert utils.get_ip_from_container('yolo') is None