2
0

test_dump.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import io
  2. import sys
  3. import pytest
  4. from flexmock import flexmock
  5. from borgmatic.hooks.data_source import dump as module
  6. def test_make_data_source_dump_path_joins_arguments():
  7. assert module.make_data_source_dump_path('/tmp', 'super_databases') == '/tmp/super_databases'
  8. def test_make_data_source_dump_filename_uses_name_and_hostname():
  9. assert (
  10. module.make_data_source_dump_filename('databases', 'test', 'hostname')
  11. == 'databases/hostname/test'
  12. )
  13. def test_make_data_source_dump_filename_uses_name_and_hostname_and_port():
  14. assert (
  15. module.make_data_source_dump_filename('databases', 'test', 'hostname', 1234)
  16. == 'databases/hostname:1234/test'
  17. )
  18. def test_make_data_source_dump_filename_without_hostname_defaults_to_localhost():
  19. assert module.make_data_source_dump_filename('databases', 'test') == 'databases/localhost/test'
  20. def test_make_data_source_dump_filename_with_invalid_name_raises():
  21. with pytest.raises(ValueError):
  22. module.make_data_source_dump_filename('databases', 'invalid/name')
  23. def test_write_data_source_dumps_metadata_writes_json_to_file():
  24. dumps_metadata = [
  25. module.borgmatic.actions.restore.Dump('databases', 'foo'),
  26. module.borgmatic.actions.restore.Dump('databases', 'bar'),
  27. ]
  28. dumps_stream = io.StringIO('password')
  29. dumps_stream.name = '/run/borgmatic/databases/dumps.json'
  30. builtins = flexmock(sys.modules['builtins'])
  31. builtins.should_receive('open').with_args(dumps_stream.name, 'w', encoding='utf-8').and_return(
  32. dumps_stream
  33. )
  34. flexmock(dumps_stream).should_receive('close') # Prevent close() so getvalue() below works.
  35. module.write_data_source_dumps_metadata('/run/borgmatic', 'databases', dumps_metadata)
  36. assert (
  37. dumps_stream.getvalue()
  38. == '[{"data_source_name": "foo", "hook_name": "databases", "hostname": "localhost", "port": null}, {"data_source_name": "bar", "hook_name": "databases", "hostname": "localhost", "port": null}]'
  39. )
  40. def test_write_data_source_dumps_metadata_with_operating_system_error_raises():
  41. dumps_metadata = [
  42. module.borgmatic.actions.restore.Dump('databases', 'foo'),
  43. module.borgmatic.actions.restore.Dump('databases', 'bar'),
  44. ]
  45. dumps_stream = io.StringIO('password')
  46. dumps_stream.name = '/run/borgmatic/databases/dumps.json'
  47. builtins = flexmock(sys.modules['builtins'])
  48. builtins.should_receive('open').with_args(dumps_stream.name, 'w', encoding='utf-8').and_raise(
  49. OSError
  50. )
  51. with pytest.raises(ValueError):
  52. module.write_data_source_dumps_metadata('/run/borgmatic', 'databases', dumps_metadata)
  53. def test_parse_data_source_dumps_metadata_converts_json_to_dump_instances():
  54. 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}]'
  55. assert module.parse_data_source_dumps_metadata(
  56. dumps_json, 'borgmatic/databases/dumps.json'
  57. ) == (
  58. module.borgmatic.actions.restore.Dump('databases', 'foo'),
  59. module.borgmatic.actions.restore.Dump('databases', 'bar', 'example.org', 1234),
  60. )
  61. def test_parse_data_source_dumps_metadata_with_invalid_json_raises():
  62. with pytest.raises(ValueError):
  63. module.parse_data_source_dumps_metadata('[{', 'borgmatic/databases/dumps.json')
  64. def test_parse_data_source_dumps_metadata_with_unknown_keys_raises():
  65. dumps_json = '[{"data_source_name": "foo", "hook_name": "databases", "wtf": "is this"}]'
  66. with pytest.raises(ValueError):
  67. module.parse_data_source_dumps_metadata(dumps_json, 'borgmatic/databases/dumps.json')
  68. def test_create_parent_directory_for_dump_does_not_raise():
  69. flexmock(module.os).should_receive('makedirs')
  70. module.create_parent_directory_for_dump('/path/to/parent')
  71. def test_create_named_pipe_for_dump_does_not_raise():
  72. flexmock(module).should_receive('create_parent_directory_for_dump')
  73. flexmock(module.os).should_receive('mkfifo')
  74. module.create_named_pipe_for_dump('/path/to/pipe')
  75. def test_remove_data_source_dumps_removes_dump_path():
  76. flexmock(module.os.path).should_receive('exists').and_return(True)
  77. flexmock(module.shutil).should_receive('rmtree').with_args('databases').once()
  78. module.remove_data_source_dumps('databases', 'SuperDB', dry_run=False)
  79. def test_remove_data_source_dumps_with_dry_run_skips_removal():
  80. flexmock(module.os.path).should_receive('exists').never()
  81. flexmock(module.shutil).should_receive('rmtree').never()
  82. module.remove_data_source_dumps('databases', 'SuperDB', dry_run=True)
  83. def test_remove_data_source_dumps_without_dump_path_present_skips_removal():
  84. flexmock(module.os.path).should_receive('exists').and_return(False)
  85. flexmock(module.shutil).should_receive('rmtree').never()
  86. module.remove_data_source_dumps('databases', 'SuperDB', dry_run=False)
  87. def test_convert_glob_patterns_to_borg_pattern_makes_multipart_regular_expression():
  88. assert (
  89. module.convert_glob_patterns_to_borg_pattern(('/etc/foo/bar', '/bar/*/baz'))
  90. == 're:(?s:etc/foo/bar)|(?s:bar/.*/baz)'
  91. )