Add tests for new code.

This commit is contained in:
Dan Helfman
2025-09-05 16:02:23 -07:00
parent 46381175ef
commit 627898cc23
3 changed files with 68 additions and 5 deletions
+2 -2
View File
@@ -305,13 +305,13 @@ def collect_dumps_from_archive(
# If we've successfully loaded any dumps metadata, we're done.
if dumps_from_archive:
logger.debug(f'Collecting database dumps from archive data source dumps metadata files')
logger.debug('Collecting database dumps from archive data source dumps metadata files')
return dumps_from_archive
# No dumps metadata files were found, so for backwards compatibility, fall back to parsing the
# paths of dumps found in the archive to get their respective dump metadata.
logger.debug(f'Collecting database dumps from archive data source dump paths (fallback)')
logger.debug('Collecting database dumps from archive data source dump paths (fallback)')
borgmatic_source_directory = str(
pathlib.Path(borgmatic.config.paths.get_borgmatic_source_directory(config)),
)
+3 -3
View File
@@ -48,7 +48,7 @@ def write_data_source_dumps_metadata(borgmatic_runtime_directory, hook_name, dum
dumps_metadata_path = os.path.join(borgmatic_runtime_directory, hook_name, 'dumps.json')
try:
with open(dumps_metadata_path, 'w') as metadata_file:
with open(dumps_metadata_path, 'w', encoding='utf-8') as metadata_file:
json.dump([dump._asdict() for dump in dumps_metadata], metadata_file, sort_keys=True)
except OSError as error:
raise ValueError(f'Error writing to dumps metadata at {dumps_metadata_path}: {error}')
@@ -56,8 +56,8 @@ def write_data_source_dumps_metadata(borgmatic_runtime_directory, hook_name, dum
def parse_data_source_dumps_metadata(dumps_json, dumps_metadata_path):
'''
Given a dumps metadata JSON string as extracted from an archive, parse it into a tuple of
borgmatic.actions.restore.Dump instances and return them.
Given a dumps metadata JSON string as extracted from an archive and its path within the archive,
parse it into a tuple of borgmatic.actions.restore.Dump instances and return them.
Raise ValueError if parsing the JSON results in a JSON decode error or the data does not have
the expected keys.
+63
View File
@@ -1,3 +1,6 @@
import io
import sys
import pytest
from flexmock import flexmock
@@ -31,6 +34,66 @@ def test_make_data_source_dump_filename_with_invalid_name_raises():
module.make_data_source_dump_filename('databases', 'invalid/name')
def test_write_data_source_dumps_metadata_writes_json_to_file():
dumps_metadata = [
module.borgmatic.actions.restore.Dump('databases', 'foo'),
module.borgmatic.actions.restore.Dump('databases', 'bar'),
]
dumps_stream = io.StringIO('password')
dumps_stream.name = '/run/borgmatic/databases/dumps.json'
builtins = flexmock(sys.modules['builtins'])
builtins.should_receive('open').with_args(dumps_stream.name, 'w', encoding='utf-8').and_return(
dumps_stream
)
flexmock(dumps_stream).should_receive('close') # Prevent close() so getvalue() below works.
module.write_data_source_dumps_metadata('/run/borgmatic', 'databases', dumps_metadata)
assert (
dumps_stream.getvalue()
== '[{"data_source_name": "foo", "hook_name": "databases", "hostname": "localhost", "port": null}, {"data_source_name": "bar", "hook_name": "databases", "hostname": "localhost", "port": null}]'
)
def test_write_data_source_dumps_metadata_with_operating_system_error_raises():
dumps_metadata = [
module.borgmatic.actions.restore.Dump('databases', 'foo'),
module.borgmatic.actions.restore.Dump('databases', 'bar'),
]
dumps_stream = io.StringIO('password')
dumps_stream.name = '/run/borgmatic/databases/dumps.json'
builtins = flexmock(sys.modules['builtins'])
builtins.should_receive('open').with_args(dumps_stream.name, 'w', encoding='utf-8').and_raise(
OSError
)
with pytest.raises(ValueError):
module.write_data_source_dumps_metadata('/run/borgmatic', 'databases', dumps_metadata)
def test_parse_data_source_dumps_metadata_converts_json_to_dump_instances():
dumps_json = '[{"data_source_name": "foo", "hook_name": "databases", "hostname": "localhost", "port": null}, {"data_source_name": "bar", "hook_name": "databases", "hostname": "example.org", "port": 1234}]'
assert module.parse_data_source_dumps_metadata(
dumps_json, 'borgmatic/databases/dumps.json'
) == (
module.borgmatic.actions.restore.Dump('databases', 'foo'),
module.borgmatic.actions.restore.Dump('databases', 'bar', 'example.org', 1234),
)
def test_parse_data_source_dumps_metadata_with_invalid_json_raises():
with pytest.raises(ValueError):
module.parse_data_source_dumps_metadata('[{', 'borgmatic/databases/dumps.json')
def test_parse_data_source_dumps_metadata_with_unknown_keys_raises():
dumps_json = '[{"data_source_name": "foo", "hook_name": "databases", "wtf": "is this"}]'
with pytest.raises(ValueError):
module.parse_data_source_dumps_metadata(dumps_json, 'borgmatic/databases/dumps.json')
def test_create_parent_directory_for_dump_does_not_raise():
flexmock(module.os).should_receive('makedirs')