test_compact.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import logging
  2. from flexmock import flexmock
  3. from borgmatic.borg import compact as module
  4. from ..test_verbosity import insert_logging_mock
  5. def insert_execute_command_mock(
  6. compact_command, output_log_level, working_directory=None, borg_exit_codes=None
  7. ):
  8. flexmock(module.environment).should_receive('make_environment')
  9. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
  10. working_directory
  11. )
  12. flexmock(module).should_receive('execute_command').with_args(
  13. compact_command,
  14. output_log_level=output_log_level,
  15. environment=None,
  16. working_directory=working_directory,
  17. borg_local_path=compact_command[0],
  18. borg_exit_codes=borg_exit_codes,
  19. ).once()
  20. COMPACT_COMMAND = ('borg', 'compact')
  21. def test_compact_segments_calls_borg_with_flags():
  22. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  23. insert_execute_command_mock(COMPACT_COMMAND + ('repo',), logging.INFO)
  24. module.compact_segments(
  25. dry_run=False,
  26. repository_path='repo',
  27. config={},
  28. local_borg_version='1.2.3',
  29. global_arguments=flexmock(),
  30. )
  31. def test_compact_segments_with_log_info_calls_borg_with_info_flag():
  32. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  33. insert_execute_command_mock(COMPACT_COMMAND + ('--info', 'repo'), logging.INFO)
  34. insert_logging_mock(logging.INFO)
  35. module.compact_segments(
  36. repository_path='repo',
  37. config={},
  38. local_borg_version='1.2.3',
  39. global_arguments=flexmock(),
  40. dry_run=False,
  41. )
  42. def test_compact_segments_with_log_debug_calls_borg_with_debug_flag():
  43. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  44. insert_execute_command_mock(COMPACT_COMMAND + ('--debug', '--show-rc', 'repo'), logging.INFO)
  45. insert_logging_mock(logging.DEBUG)
  46. module.compact_segments(
  47. repository_path='repo',
  48. config={},
  49. local_borg_version='1.2.3',
  50. global_arguments=flexmock(),
  51. dry_run=False,
  52. )
  53. def test_compact_segments_with_dry_run_skips_borg_call_when_feature_unavailable():
  54. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  55. flexmock(module.feature).should_receive('available').with_args(
  56. module.feature.Feature.DRY_RUN_COMPACT, '1.2.3'
  57. ).and_return(False)
  58. flexmock(module.environment).should_receive('make_environment').never()
  59. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').never()
  60. flexmock(module).should_receive('execute_command').never()
  61. flexmock(logging).should_receive('info').with_args('Skipping compact (dry run)').once()
  62. module.compact_segments(
  63. repository_path='repo',
  64. config={},
  65. local_borg_version='1.2.3',
  66. global_arguments=flexmock(),
  67. dry_run=True,
  68. )
  69. def test_compact_segments_with_dry_run_executes_borg_call_when_feature_available():
  70. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  71. flexmock(module.feature).should_receive('available').with_args(
  72. module.feature.Feature.DRY_RUN_COMPACT, '1.4.1'
  73. ).and_return(True)
  74. flexmock(module.environment).should_receive('make_environment').once()
  75. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').once()
  76. flexmock(module).should_receive('execute_command').once()
  77. module.compact_segments(
  78. repository_path='repo',
  79. config={},
  80. local_borg_version='1.4.1',
  81. global_arguments=flexmock(),
  82. dry_run=True,
  83. )
  84. def test_compact_segments_with_local_path_calls_borg_via_local_path():
  85. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  86. insert_execute_command_mock(('borg1',) + COMPACT_COMMAND[1:] + ('repo',), logging.INFO)
  87. module.compact_segments(
  88. dry_run=False,
  89. repository_path='repo',
  90. config={},
  91. local_borg_version='1.2.3',
  92. global_arguments=flexmock(),
  93. local_path='borg1',
  94. )
  95. def test_compact_segments_with_exit_codes_calls_borg_using_them():
  96. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  97. borg_exit_codes = flexmock()
  98. insert_execute_command_mock(
  99. COMPACT_COMMAND + ('repo',), logging.INFO, borg_exit_codes=borg_exit_codes
  100. )
  101. module.compact_segments(
  102. dry_run=False,
  103. repository_path='repo',
  104. config={'borg_exit_codes': borg_exit_codes},
  105. local_borg_version='1.2.3',
  106. global_arguments=flexmock(),
  107. )
  108. def test_compact_segments_with_remote_path_calls_borg_with_remote_path_flags():
  109. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  110. insert_execute_command_mock(COMPACT_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO)
  111. module.compact_segments(
  112. dry_run=False,
  113. repository_path='repo',
  114. config={},
  115. local_borg_version='1.2.3',
  116. global_arguments=flexmock(),
  117. remote_path='borg1',
  118. )
  119. def test_compact_segments_with_progress_calls_borg_with_progress_flag():
  120. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  121. insert_execute_command_mock(COMPACT_COMMAND + ('--progress', 'repo'), logging.INFO)
  122. module.compact_segments(
  123. dry_run=False,
  124. repository_path='repo',
  125. config={'progress': True},
  126. local_borg_version='1.2.3',
  127. global_arguments=flexmock(),
  128. )
  129. def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_flag():
  130. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  131. insert_execute_command_mock(COMPACT_COMMAND + ('--cleanup-commits', 'repo'), logging.INFO)
  132. module.compact_segments(
  133. dry_run=False,
  134. repository_path='repo',
  135. config={},
  136. local_borg_version='1.2.3',
  137. global_arguments=flexmock(),
  138. cleanup_commits=True,
  139. )
  140. def test_compact_segments_with_threshold_calls_borg_with_threshold_flag():
  141. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  142. insert_execute_command_mock(COMPACT_COMMAND + ('--threshold', '20', 'repo'), logging.INFO)
  143. module.compact_segments(
  144. dry_run=False,
  145. repository_path='repo',
  146. config={'compact_threshold': 20},
  147. local_borg_version='1.2.3',
  148. global_arguments=flexmock(),
  149. )
  150. def test_compact_segments_with_umask_calls_borg_with_umask_flags():
  151. config = {'umask': '077'}
  152. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  153. insert_execute_command_mock(COMPACT_COMMAND + ('--umask', '077', 'repo'), logging.INFO)
  154. module.compact_segments(
  155. dry_run=False,
  156. repository_path='repo',
  157. config=config,
  158. local_borg_version='1.2.3',
  159. global_arguments=flexmock(),
  160. )
  161. def test_compact_segments_with_log_json_calls_borg_with_log_json_flags():
  162. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  163. insert_execute_command_mock(COMPACT_COMMAND + ('--log-json', 'repo'), logging.INFO)
  164. module.compact_segments(
  165. dry_run=False,
  166. repository_path='repo',
  167. config={'log_json': True},
  168. local_borg_version='1.2.3',
  169. global_arguments=flexmock(),
  170. )
  171. def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_flags():
  172. config = {'lock_wait': 5}
  173. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  174. insert_execute_command_mock(COMPACT_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO)
  175. module.compact_segments(
  176. dry_run=False,
  177. repository_path='repo',
  178. config=config,
  179. local_borg_version='1.2.3',
  180. global_arguments=flexmock(),
  181. )
  182. def test_compact_segments_with_extra_borg_options_calls_borg_with_extra_options():
  183. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  184. insert_execute_command_mock(COMPACT_COMMAND + ('--extra', '--options', 'repo'), logging.INFO)
  185. module.compact_segments(
  186. dry_run=False,
  187. repository_path='repo',
  188. config={'extra_borg_options': {'compact': '--extra --options'}},
  189. local_borg_version='1.2.3',
  190. global_arguments=flexmock(),
  191. )
  192. def test_compact_segments_calls_borg_with_working_directory():
  193. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  194. insert_execute_command_mock(
  195. COMPACT_COMMAND + ('repo',), logging.INFO, working_directory='/working/dir'
  196. )
  197. module.compact_segments(
  198. dry_run=False,
  199. repository_path='repo',
  200. config={'working_directory': '/working/dir'},
  201. local_borg_version='1.2.3',
  202. global_arguments=flexmock(),
  203. )