test_sqlite.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import logging
  2. from flexmock import flexmock
  3. from borgmatic.hooks import sqlite as module
  4. def test_dump_data_sources_logs_and_skips_if_dump_already_exists():
  5. databases = [{'path': '/path/to/database', 'name': 'database'}]
  6. flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
  7. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  8. '/path/to/dump/database'
  9. )
  10. flexmock(module.os.path).should_receive('exists').and_return(True)
  11. flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
  12. flexmock(module).should_receive('execute_command').never()
  13. assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == []
  14. def test_dump_data_sources_dumps_each_database():
  15. databases = [
  16. {'path': '/path/to/database1', 'name': 'database1'},
  17. {'path': '/path/to/database2', 'name': 'database2'},
  18. ]
  19. processes = [flexmock(), flexmock()]
  20. flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
  21. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  22. '/path/to/dump/database'
  23. )
  24. flexmock(module.os.path).should_receive('exists').and_return(False)
  25. flexmock(module.dump).should_receive('create_parent_directory_for_dump')
  26. flexmock(module).should_receive('execute_command').and_return(processes[0]).and_return(
  27. processes[1]
  28. )
  29. assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
  30. def test_dumping_database_with_non_existent_path_warns_and_dumps_database():
  31. databases = [
  32. {'path': '/path/to/database1', 'name': 'database1'},
  33. ]
  34. processes = [flexmock()]
  35. flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
  36. flexmock(module.logger).should_receive('warning').once()
  37. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  38. '/path/to/dump/database'
  39. )
  40. flexmock(module.os.path).should_receive('exists').and_return(False)
  41. flexmock(module.dump).should_receive('create_parent_directory_for_dump')
  42. flexmock(module).should_receive('execute_command').and_return(processes[0])
  43. assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
  44. def test_dumping_database_with_name_all_warns_and_dumps_all_databases():
  45. databases = [
  46. {'path': '/path/to/database1', 'name': 'all'},
  47. ]
  48. processes = [flexmock()]
  49. flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
  50. flexmock(module.logger).should_receive(
  51. 'warning'
  52. ).twice() # once for the name=all, once for the non-existent path
  53. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  54. '/path/to/dump/database'
  55. )
  56. flexmock(module.os.path).should_receive('exists').and_return(False)
  57. flexmock(module.dump).should_receive('create_parent_directory_for_dump')
  58. flexmock(module).should_receive('execute_command').and_return(processes[0])
  59. assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=False) == processes
  60. def test_dump_data_sources_does_not_dump_if_dry_run():
  61. databases = [{'path': '/path/to/database', 'name': 'database'}]
  62. flexmock(module).should_receive('make_dump_path').and_return('/path/to/dump')
  63. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  64. '/path/to/dump/database'
  65. )
  66. flexmock(module.os.path).should_receive('exists').and_return(False)
  67. flexmock(module.dump).should_receive('create_parent_directory_for_dump').never()
  68. flexmock(module).should_receive('execute_command').never()
  69. assert module.dump_data_sources(databases, {}, 'test.yaml', dry_run=True) == []
  70. def test_restore_data_source_dump_restores_database():
  71. hook_config = [{'path': '/path/to/database', 'name': 'database'}, {'name': 'other'}]
  72. extract_process = flexmock(stdout=flexmock())
  73. flexmock(module).should_receive('execute_command_with_processes').with_args(
  74. (
  75. 'sqlite3',
  76. '/path/to/database',
  77. ),
  78. processes=[extract_process],
  79. output_log_level=logging.DEBUG,
  80. input_file=extract_process.stdout,
  81. ).once()
  82. flexmock(module.os).should_receive('remove').once()
  83. module.restore_data_source_dump(
  84. hook_config,
  85. {},
  86. 'test.yaml',
  87. data_source=hook_config[0],
  88. dry_run=False,
  89. extract_process=extract_process,
  90. connection_params={'restore_path': None},
  91. )
  92. def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
  93. hook_config = [
  94. {'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
  95. ]
  96. extract_process = flexmock(stdout=flexmock())
  97. flexmock(module).should_receive('execute_command_with_processes').with_args(
  98. (
  99. 'sqlite3',
  100. 'cli/path/to/database',
  101. ),
  102. processes=[extract_process],
  103. output_log_level=logging.DEBUG,
  104. input_file=extract_process.stdout,
  105. ).once()
  106. flexmock(module.os).should_receive('remove').once()
  107. module.restore_data_source_dump(
  108. hook_config,
  109. {},
  110. 'test.yaml',
  111. data_source={'name': 'database'},
  112. dry_run=False,
  113. extract_process=extract_process,
  114. connection_params={'restore_path': 'cli/path/to/database'},
  115. )
  116. def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
  117. hook_config = [
  118. {'path': '/path/to/database', 'name': 'database', 'restore_path': 'config/path/to/database'}
  119. ]
  120. extract_process = flexmock(stdout=flexmock())
  121. flexmock(module).should_receive('execute_command_with_processes').with_args(
  122. (
  123. 'sqlite3',
  124. 'config/path/to/database',
  125. ),
  126. processes=[extract_process],
  127. output_log_level=logging.DEBUG,
  128. input_file=extract_process.stdout,
  129. ).once()
  130. flexmock(module.os).should_receive('remove').once()
  131. module.restore_data_source_dump(
  132. hook_config,
  133. {},
  134. 'test.yaml',
  135. data_source=hook_config[0],
  136. dry_run=False,
  137. extract_process=extract_process,
  138. connection_params={'restore_path': None},
  139. )
  140. def test_restore_data_source_dump_does_not_restore_database_if_dry_run():
  141. hook_config = [{'path': '/path/to/database', 'name': 'database'}]
  142. extract_process = flexmock(stdout=flexmock())
  143. flexmock(module).should_receive('execute_command_with_processes').never()
  144. flexmock(module.os).should_receive('remove').never()
  145. module.restore_data_source_dump(
  146. hook_config,
  147. {},
  148. 'test.yaml',
  149. data_source={'name': 'database'},
  150. dry_run=True,
  151. extract_process=extract_process,
  152. connection_params={'restore_path': None},
  153. )