Procházet zdrojové kódy

Add even more missing test coverage (#418).

Dan Helfman před 5 měsíci
rodič
revize
be6b865a81

+ 1 - 1
borgmatic/actions/restore.py

@@ -96,7 +96,7 @@ def get_configured_data_source(config, restore_dump):
 
     if len(matching_dumps) > 1:
         raise ValueError(
-            f'Cannot restore data source {render_dump_metadata(restore_dump)} because there are multiple matching configured data sources'
+            f'Cannot restore data source {render_dump_metadata(restore_dump)} because there are multiple matching data sources configured'
         )
 
     return matching_dumps[0]

+ 163 - 3
tests/unit/actions/test_restore.py

@@ -399,7 +399,7 @@ def test_collect_dumps_from_archive_parses_archive_paths():
     flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
         [
             'borgmatic/postgresql_databases/localhost/foo',
-            'borgmatic/postgresql_databases/localhost/bar',
+            'borgmatic/postgresql_databases/host:1234/bar',
             'borgmatic/mysql_databases/localhost/quux',
         ]
     )
@@ -417,7 +417,7 @@ def test_collect_dumps_from_archive_parses_archive_paths():
 
     assert archive_dumps == {
         module.Dump('postgresql_databases', 'foo'),
-        module.Dump('postgresql_databases', 'bar'),
+        module.Dump('postgresql_databases', 'bar', 'host', 1234),
         module.Dump('mysql_databases', 'quux'),
     }
 
@@ -487,7 +487,7 @@ def test_collect_dumps_from_archive_parses_directory_format_archive_paths():
     }
 
 
-def test_collect_dumps_from_archive_skips_bad_archive_paths():
+def test_collect_dumps_from_archive_skips_bad_archive_paths_or_bad_path_components():
     flexmock(module.borgmatic.config.paths).should_receive(
         'get_borgmatic_source_directory'
     ).and_return('/root/.borgmatic')
@@ -497,6 +497,7 @@ def test_collect_dumps_from_archive_skips_bad_archive_paths():
     flexmock(module.borgmatic.borg.list).should_receive('capture_archive_listing').and_return(
         [
             'borgmatic/postgresql_databases/localhost/foo',
+            'borgmatic/postgresql_databases/localhost:abcd/bar',
             'borgmatic/invalid',
             'invalid/as/well',
             '',
@@ -516,6 +517,7 @@ def test_collect_dumps_from_archive_skips_bad_archive_paths():
 
     assert archive_dumps == {
         module.Dump('postgresql_databases', 'foo'),
+        module.Dump('postgresql_databases', 'bar'),
     }
 
 
@@ -694,6 +696,106 @@ def test_get_dumps_to_restore_raises_for_all_in_requested_dumps_and_requested_du
         )
 
 
+def test_get_dumps_to_restore_with_requested_hook_name_filters_dumps_found_in_archive():
+    dumps_from_archive = {
+        module.Dump('mariadb_databases', 'foo'),
+        module.Dump('postgresql_databases', 'foo'),
+        module.Dump('sqlite_databases', 'bar'),
+    }
+    flexmock(module).should_receive('dumps_match').and_return(False)
+    flexmock(module).should_receive('dumps_match').with_args(
+        module.Dump('postgresql_databases', 'foo'),
+        module.Dump('postgresql_databases', 'foo'),
+    ).and_return(True)
+
+    assert module.get_dumps_to_restore(
+        restore_arguments=flexmock(
+            hook='postgresql_databases',
+            data_sources=['foo'],
+            original_hostname=None,
+            original_port=None,
+        ),
+        dumps_from_archive=dumps_from_archive,
+    ) == {
+        module.Dump('postgresql_databases', 'foo'),
+    }
+
+
+def test_get_dumps_to_restore_with_requested_shortened_hook_name_filters_dumps_found_in_archive():
+    dumps_from_archive = {
+        module.Dump('mariadb_databases', 'foo'),
+        module.Dump('postgresql_databases', 'foo'),
+        module.Dump('sqlite_databases', 'bar'),
+    }
+    flexmock(module).should_receive('dumps_match').and_return(False)
+    flexmock(module).should_receive('dumps_match').with_args(
+        module.Dump('postgresql_databases', 'foo'),
+        module.Dump('postgresql_databases', 'foo'),
+    ).and_return(True)
+
+    assert module.get_dumps_to_restore(
+        restore_arguments=flexmock(
+            hook='postgresql',
+            data_sources=['foo'],
+            original_hostname=None,
+            original_port=None,
+        ),
+        dumps_from_archive=dumps_from_archive,
+    ) == {
+        module.Dump('postgresql_databases', 'foo'),
+    }
+
+
+def test_get_dumps_to_restore_with_requested_hostname_filters_dumps_found_in_archive():
+    dumps_from_archive = {
+        module.Dump('postgresql_databases', 'foo'),
+        module.Dump('postgresql_databases', 'foo', 'host'),
+        module.Dump('postgresql_databases', 'bar'),
+    }
+    flexmock(module).should_receive('dumps_match').and_return(False)
+    flexmock(module).should_receive('dumps_match').with_args(
+        module.Dump('postgresql_databases', 'foo', 'host'),
+        module.Dump('postgresql_databases', 'foo', 'host'),
+    ).and_return(True)
+
+    assert module.get_dumps_to_restore(
+        restore_arguments=flexmock(
+            hook='postgresql_databases',
+            data_sources=['foo'],
+            original_hostname='host',
+            original_port=None,
+        ),
+        dumps_from_archive=dumps_from_archive,
+    ) == {
+        module.Dump('postgresql_databases', 'foo', 'host'),
+    }
+
+
+def test_get_dumps_to_restore_with_requested_port_filters_dumps_found_in_archive():
+    dumps_from_archive = {
+        module.Dump('postgresql_databases', 'foo', 'host'),
+        module.Dump('postgresql_databases', 'foo', 'host', 1234),
+        module.Dump('postgresql_databases', 'bar'),
+    }
+    flexmock(module).should_receive('dumps_match').and_return(False)
+    flexmock(module).should_receive('dumps_match').with_args(
+        module.Dump('postgresql_databases', 'foo', 'host', 1234),
+        module.Dump('postgresql_databases', 'foo', 'host', 1234),
+    ).and_return(True)
+
+    assert module.get_dumps_to_restore(
+        restore_arguments=flexmock(
+            hook='postgresql_databases',
+            data_sources=['foo'],
+            original_hostname='host',
+            original_port=1234,
+        ),
+        dumps_from_archive=dumps_from_archive,
+    ) == {
+        module.Dump('postgresql_databases', 'foo', 'host', 1234),
+    }
+
+
 def test_ensure_requested_dumps_restored_with_all_dumps_restored_does_not_raise():
     module.ensure_requested_dumps_restored(
         dumps_to_restore={
@@ -827,6 +929,64 @@ def test_run_restore_bails_for_non_matching_repository():
     )
 
 
+def test_run_restore_restores_data_source_by_falling_back_to_all_name():
+    dumps_to_restore = {
+        module.Dump(hook_name='postgresql_databases', data_source_name='foo'),
+    }
+
+    flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
+    borgmatic_runtime_directory = flexmock()
+    flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
+        borgmatic_runtime_directory
+    )
+    flexmock(module.borgmatic.config.paths).should_receive(
+        'make_runtime_directory_glob'
+    ).replace_with(lambda path: path)
+    flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hooks_even_if_unconfigured')
+    flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
+        flexmock()
+    )
+    flexmock(module).should_receive('collect_dumps_from_archive').and_return(flexmock())
+    flexmock(module).should_receive('get_dumps_to_restore').and_return(dumps_to_restore)
+    flexmock(module).should_receive('get_configured_data_source').and_return(
+        {'name': 'foo'}
+    ).and_return({'name': 'all'})
+    flexmock(module).should_receive('restore_single_dump').with_args(
+        repository=object,
+        config=object,
+        local_borg_version=object,
+        global_arguments=object,
+        local_path=object,
+        remote_path=object,
+        archive_name=object,
+        hook_name='postgresql_databases',
+        data_source={'name': 'foo', 'schemas': None},
+        connection_params=object,
+        borgmatic_runtime_directory=borgmatic_runtime_directory,
+    ).once()
+    flexmock(module).should_receive('ensure_requested_dumps_restored')
+
+    module.run_restore(
+        repository={'path': 'repo'},
+        config=flexmock(),
+        local_borg_version=flexmock(),
+        restore_arguments=flexmock(
+            repository='repo',
+            archive='archive',
+            data_sources=flexmock(),
+            schemas=None,
+            hostname=None,
+            port=None,
+            username=None,
+            password=None,
+            restore_path=None,
+        ),
+        global_arguments=flexmock(dry_run=False),
+        local_path=flexmock(),
+        remote_path=flexmock(),
+    )
+
+
 def test_run_restore_restores_data_source_configured_with_all_name():
     dumps_to_restore = {
         module.Dump(hook_name='postgresql_databases', data_source_name='foo'),

+ 7 - 0
tests/unit/hooks/data_source/test_dump.py

@@ -15,6 +15,13 @@ def test_make_data_source_dump_filename_uses_name_and_hostname():
     )
 
 
+def test_make_data_source_dump_filename_uses_name_and_hostname_and_port():
+    assert (
+        module.make_data_source_dump_filename('databases', 'test', 'hostname', 1234)
+        == 'databases/hostname:1234/test'
+    )
+
+
 def test_make_data_source_dump_filename_without_hostname_defaults_to_localhost():
     assert module.make_data_source_dump_filename('databases', 'test') == 'databases/localhost/test'