test_compact.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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).should_receive('execute_command').never()
  59. flexmock(logging).should_receive('info').with_args('Skipping compact (dry run)').once()
  60. module.compact_segments(
  61. repository_path='repo',
  62. config={},
  63. local_borg_version='1.2.3',
  64. global_arguments=flexmock(),
  65. dry_run=True,
  66. )
  67. def test_compact_segments_with_dry_run_executes_borg_call_when_feature_available():
  68. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  69. flexmock(module.feature).should_receive('available').with_args(
  70. module.feature.Feature.DRY_RUN_COMPACT, '1.4.1'
  71. ).and_return(True)
  72. flexmock(module).should_receive('execute_command').once()
  73. module.compact_segments(
  74. repository_path='repo',
  75. config={},
  76. local_borg_version='1.4.1',
  77. global_arguments=flexmock(),
  78. dry_run=True,
  79. )
  80. def test_compact_segments_with_local_path_calls_borg_via_local_path():
  81. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  82. insert_execute_command_mock(('borg1',) + COMPACT_COMMAND[1:] + ('repo',), logging.INFO)
  83. module.compact_segments(
  84. dry_run=False,
  85. repository_path='repo',
  86. config={},
  87. local_borg_version='1.2.3',
  88. global_arguments=flexmock(),
  89. local_path='borg1',
  90. )
  91. def test_compact_segments_with_exit_codes_calls_borg_using_them():
  92. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  93. borg_exit_codes = flexmock()
  94. insert_execute_command_mock(
  95. COMPACT_COMMAND + ('repo',), logging.INFO, borg_exit_codes=borg_exit_codes
  96. )
  97. module.compact_segments(
  98. dry_run=False,
  99. repository_path='repo',
  100. config={'borg_exit_codes': borg_exit_codes},
  101. local_borg_version='1.2.3',
  102. global_arguments=flexmock(),
  103. )
  104. def test_compact_segments_with_remote_path_calls_borg_with_remote_path_flags():
  105. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  106. insert_execute_command_mock(COMPACT_COMMAND + ('--remote-path', 'borg1', 'repo'), logging.INFO)
  107. module.compact_segments(
  108. dry_run=False,
  109. repository_path='repo',
  110. config={},
  111. local_borg_version='1.2.3',
  112. global_arguments=flexmock(),
  113. remote_path='borg1',
  114. )
  115. def test_compact_segments_with_progress_calls_borg_with_progress_flag():
  116. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  117. insert_execute_command_mock(COMPACT_COMMAND + ('--progress', 'repo'), logging.INFO)
  118. module.compact_segments(
  119. dry_run=False,
  120. repository_path='repo',
  121. config={'progress': True},
  122. local_borg_version='1.2.3',
  123. global_arguments=flexmock(),
  124. )
  125. def test_compact_segments_with_cleanup_commits_calls_borg_with_cleanup_commits_flag():
  126. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  127. insert_execute_command_mock(COMPACT_COMMAND + ('--cleanup-commits', 'repo'), logging.INFO)
  128. module.compact_segments(
  129. dry_run=False,
  130. repository_path='repo',
  131. config={},
  132. local_borg_version='1.2.3',
  133. global_arguments=flexmock(),
  134. cleanup_commits=True,
  135. )
  136. def test_compact_segments_with_threshold_calls_borg_with_threshold_flag():
  137. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  138. insert_execute_command_mock(COMPACT_COMMAND + ('--threshold', '20', 'repo'), logging.INFO)
  139. module.compact_segments(
  140. dry_run=False,
  141. repository_path='repo',
  142. config={'compact_threshold': 20},
  143. local_borg_version='1.2.3',
  144. global_arguments=flexmock(),
  145. )
  146. def test_compact_segments_with_umask_calls_borg_with_umask_flags():
  147. config = {'umask': '077'}
  148. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  149. insert_execute_command_mock(COMPACT_COMMAND + ('--umask', '077', 'repo'), logging.INFO)
  150. module.compact_segments(
  151. dry_run=False,
  152. repository_path='repo',
  153. config=config,
  154. local_borg_version='1.2.3',
  155. global_arguments=flexmock(),
  156. )
  157. def test_compact_segments_with_log_json_calls_borg_with_log_json_flags():
  158. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  159. insert_execute_command_mock(COMPACT_COMMAND + ('--log-json', 'repo'), logging.INFO)
  160. module.compact_segments(
  161. dry_run=False,
  162. repository_path='repo',
  163. config={'log_json': True},
  164. local_borg_version='1.2.3',
  165. global_arguments=flexmock(),
  166. )
  167. def test_compact_segments_with_lock_wait_calls_borg_with_lock_wait_flags():
  168. config = {'lock_wait': 5}
  169. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  170. insert_execute_command_mock(COMPACT_COMMAND + ('--lock-wait', '5', 'repo'), logging.INFO)
  171. module.compact_segments(
  172. dry_run=False,
  173. repository_path='repo',
  174. config=config,
  175. local_borg_version='1.2.3',
  176. global_arguments=flexmock(),
  177. )
  178. def test_compact_segments_with_extra_borg_options_calls_borg_with_extra_options():
  179. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  180. insert_execute_command_mock(COMPACT_COMMAND + ('--extra', '--options', 'repo'), logging.INFO)
  181. module.compact_segments(
  182. dry_run=False,
  183. repository_path='repo',
  184. config={'extra_borg_options': {'compact': '--extra --options'}},
  185. local_borg_version='1.2.3',
  186. global_arguments=flexmock(),
  187. )
  188. def test_compact_segments_calls_borg_with_working_directory():
  189. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  190. insert_execute_command_mock(
  191. COMPACT_COMMAND + ('repo',), logging.INFO, working_directory='/working/dir'
  192. )
  193. module.compact_segments(
  194. dry_run=False,
  195. repository_path='repo',
  196. config={'working_directory': '/working/dir'},
  197. local_borg_version='1.2.3',
  198. global_arguments=flexmock(),
  199. )