test_check.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. from subprocess import STDOUT
  2. import logging
  3. import sys
  4. from flexmock import flexmock
  5. import pytest
  6. from borgmatic.borg import check as module
  7. from ..test_verbosity import insert_logging_mock
  8. def insert_subprocess_mock(check_call_command, **kwargs):
  9. subprocess = flexmock(module.subprocess)
  10. subprocess.should_receive('check_call').with_args(check_call_command, **kwargs).once()
  11. def insert_subprocess_never():
  12. subprocess = flexmock(module.subprocess)
  13. subprocess.should_receive('check_call').never()
  14. def test_parse_checks_returns_them_as_tuple():
  15. checks = module._parse_checks({'checks': ['foo', 'disabled', 'bar']})
  16. assert checks == ('foo', 'bar')
  17. def test_parse_checks_with_missing_value_returns_defaults():
  18. checks = module._parse_checks({})
  19. assert checks == module.DEFAULT_CHECKS
  20. def test_parse_checks_with_blank_value_returns_defaults():
  21. checks = module._parse_checks({'checks': []})
  22. assert checks == module.DEFAULT_CHECKS
  23. def test_parse_checks_with_disabled_returns_no_checks():
  24. checks = module._parse_checks({'checks': ['disabled']})
  25. assert checks == ()
  26. def test_make_check_flags_with_repository_check_returns_flag():
  27. flags = module._make_check_flags(('repository',))
  28. assert flags == ('--repository-only',)
  29. def test_make_check_flags_with_extract_omits_extract_flag():
  30. flags = module._make_check_flags(('extract',))
  31. assert flags == ()
  32. def test_make_check_flags_with_default_checks_returns_default_flags():
  33. flags = module._make_check_flags(module.DEFAULT_CHECKS)
  34. assert flags == ('--prefix', module.DEFAULT_PREFIX)
  35. def test_make_check_flags_with_all_checks_returns_default_flags():
  36. flags = module._make_check_flags(module.DEFAULT_CHECKS + ('extract',))
  37. assert flags == ('--prefix', module.DEFAULT_PREFIX)
  38. def test_make_check_flags_with_archives_check_and_last_includes_last_flag():
  39. flags = module._make_check_flags(('archives',), check_last=3)
  40. assert flags == ('--archives-only', '--last', '3', '--prefix', module.DEFAULT_PREFIX)
  41. def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
  42. flags = module._make_check_flags(('repository',), check_last=3)
  43. assert flags == ('--repository-only',)
  44. def test_make_check_flags_with_default_checks_and_last_includes_last_flag():
  45. flags = module._make_check_flags(module.DEFAULT_CHECKS, check_last=3)
  46. assert flags == ('--last', '3', '--prefix', module.DEFAULT_PREFIX)
  47. def test_make_check_flags_with_archives_check_and_prefix_includes_prefix_flag():
  48. flags = module._make_check_flags(('archives',), prefix='foo-')
  49. assert flags == ('--archives-only', '--prefix', 'foo-')
  50. def test_make_check_flags_with_repository_check_and_prefix_omits_prefix_flag():
  51. flags = module._make_check_flags(('repository',), prefix='foo-')
  52. assert flags == ('--repository-only',)
  53. def test_make_check_flags_with_default_checks_and_prefix_includes_prefix_flag():
  54. flags = module._make_check_flags(module.DEFAULT_CHECKS, prefix='foo-')
  55. assert flags == ('--prefix', 'foo-')
  56. @pytest.mark.parametrize(
  57. 'checks',
  58. (
  59. ('repository',),
  60. ('archives',),
  61. ('repository', 'archives'),
  62. ('repository', 'archives', 'other'),
  63. ),
  64. )
  65. def test_check_archives_calls_borg_with_parameters(checks):
  66. check_last = flexmock()
  67. consistency_config = {'check_last': check_last}
  68. flexmock(module).should_receive('_parse_checks').and_return(checks)
  69. flexmock(module).should_receive('_make_check_flags').with_args(
  70. checks, check_last, None
  71. ).and_return(())
  72. stdout = flexmock()
  73. insert_subprocess_mock(('borg', 'check', 'repo'), stdout=stdout, stderr=STDOUT)
  74. flexmock(sys.modules['builtins']).should_receive('open').and_return(stdout)
  75. flexmock(module.os).should_receive('devnull')
  76. module.check_archives(
  77. repository='repo', storage_config={}, consistency_config=consistency_config
  78. )
  79. def test_check_archives_with_extract_check_calls_extract_only():
  80. checks = ('extract',)
  81. check_last = flexmock()
  82. consistency_config = {'check_last': check_last}
  83. flexmock(module).should_receive('_parse_checks').and_return(checks)
  84. flexmock(module).should_receive('_make_check_flags').never()
  85. flexmock(module.extract).should_receive('extract_last_archive_dry_run').once()
  86. insert_subprocess_never()
  87. module.check_archives(
  88. repository='repo', storage_config={}, consistency_config=consistency_config
  89. )
  90. def test_check_archives_with_log_info_calls_borg_with_info_parameter():
  91. checks = ('repository',)
  92. consistency_config = {'check_last': None}
  93. flexmock(module).should_receive('_parse_checks').and_return(checks)
  94. flexmock(module).should_receive('_make_check_flags').and_return(())
  95. insert_logging_mock(logging.INFO)
  96. insert_subprocess_mock(('borg', 'check', 'repo', '--info'), stdout=None, stderr=STDOUT)
  97. module.check_archives(
  98. repository='repo', storage_config={}, consistency_config=consistency_config
  99. )
  100. def test_check_archives_with_log_debug_calls_borg_with_debug_parameter():
  101. checks = ('repository',)
  102. consistency_config = {'check_last': None}
  103. flexmock(module).should_receive('_parse_checks').and_return(checks)
  104. flexmock(module).should_receive('_make_check_flags').and_return(())
  105. insert_logging_mock(logging.DEBUG)
  106. insert_subprocess_mock(
  107. ('borg', 'check', 'repo', '--debug', '--show-rc'), stdout=None, stderr=STDOUT
  108. )
  109. module.check_archives(
  110. repository='repo', storage_config={}, consistency_config=consistency_config
  111. )
  112. def test_check_archives_without_any_checks_bails():
  113. consistency_config = {'check_last': None}
  114. flexmock(module).should_receive('_parse_checks').and_return(())
  115. insert_subprocess_never()
  116. module.check_archives(
  117. repository='repo', storage_config={}, consistency_config=consistency_config
  118. )
  119. def test_check_archives_with_local_path_calls_borg_via_local_path():
  120. checks = ('repository',)
  121. check_last = flexmock()
  122. consistency_config = {'check_last': check_last}
  123. flexmock(module).should_receive('_parse_checks').and_return(checks)
  124. flexmock(module).should_receive('_make_check_flags').with_args(
  125. checks, check_last, None
  126. ).and_return(())
  127. stdout = flexmock()
  128. insert_subprocess_mock(('borg1', 'check', 'repo'), stdout=stdout, stderr=STDOUT)
  129. flexmock(sys.modules['builtins']).should_receive('open').and_return(stdout)
  130. flexmock(module.os).should_receive('devnull')
  131. module.check_archives(
  132. repository='repo',
  133. storage_config={},
  134. consistency_config=consistency_config,
  135. local_path='borg1',
  136. )
  137. def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters():
  138. checks = ('repository',)
  139. check_last = flexmock()
  140. consistency_config = {'check_last': check_last}
  141. flexmock(module).should_receive('_parse_checks').and_return(checks)
  142. flexmock(module).should_receive('_make_check_flags').with_args(
  143. checks, check_last, None
  144. ).and_return(())
  145. stdout = flexmock()
  146. insert_subprocess_mock(
  147. ('borg', 'check', 'repo', '--remote-path', 'borg1'), stdout=stdout, stderr=STDOUT
  148. )
  149. flexmock(sys.modules['builtins']).should_receive('open').and_return(stdout)
  150. flexmock(module.os).should_receive('devnull')
  151. module.check_archives(
  152. repository='repo',
  153. storage_config={},
  154. consistency_config=consistency_config,
  155. remote_path='borg1',
  156. )
  157. def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
  158. checks = ('repository',)
  159. check_last = flexmock()
  160. consistency_config = {'check_last': check_last}
  161. flexmock(module).should_receive('_parse_checks').and_return(checks)
  162. flexmock(module).should_receive('_make_check_flags').with_args(
  163. checks, check_last, None
  164. ).and_return(())
  165. stdout = flexmock()
  166. insert_subprocess_mock(
  167. ('borg', 'check', 'repo', '--lock-wait', '5'), stdout=stdout, stderr=STDOUT
  168. )
  169. flexmock(sys.modules['builtins']).should_receive('open').and_return(stdout)
  170. flexmock(module.os).should_receive('devnull')
  171. module.check_archives(
  172. repository='repo', storage_config={'lock_wait': 5}, consistency_config=consistency_config
  173. )
  174. def test_check_archives_with_retention_prefix():
  175. checks = ('repository',)
  176. check_last = flexmock()
  177. prefix = 'foo-'
  178. consistency_config = {'check_last': check_last, 'prefix': prefix}
  179. flexmock(module).should_receive('_parse_checks').and_return(checks)
  180. flexmock(module).should_receive('_make_check_flags').with_args(
  181. checks, check_last, prefix
  182. ).and_return(())
  183. stdout = flexmock()
  184. insert_subprocess_mock(('borg', 'check', 'repo'), stdout=stdout, stderr=STDOUT)
  185. flexmock(sys.modules['builtins']).should_receive('open').and_return(stdout)
  186. flexmock(module.os).should_receive('devnull')
  187. module.check_archives(
  188. repository='repo', storage_config={}, consistency_config=consistency_config
  189. )