test_check.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. import logging
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic.borg import check as module
  5. from ..test_verbosity import insert_logging_mock
  6. def insert_execute_command_mock(command):
  7. flexmock(module.environment).should_receive('make_environment')
  8. flexmock(module).should_receive('execute_command').with_args(
  9. command, extra_environment=None
  10. ).once()
  11. def insert_execute_command_never():
  12. flexmock(module).should_receive('execute_command').never()
  13. def test_parse_checks_returns_them_as_tuple():
  14. checks = module.parse_checks({'checks': [{'name': 'foo'}, {'name': 'bar'}]})
  15. assert checks == ('foo', 'bar')
  16. def test_parse_checks_with_missing_value_returns_defaults():
  17. checks = module.parse_checks({})
  18. assert checks == ('repository', 'archives')
  19. def test_parse_checks_with_empty_list_returns_defaults():
  20. checks = module.parse_checks({'checks': []})
  21. assert checks == ('repository', 'archives')
  22. def test_parse_checks_with_none_value_returns_defaults():
  23. checks = module.parse_checks({'checks': None})
  24. assert checks == ('repository', 'archives')
  25. def test_parse_checks_with_disabled_returns_no_checks():
  26. checks = module.parse_checks({'checks': [{'name': 'foo'}, {'name': 'disabled'}]})
  27. assert checks == ()
  28. def test_parse_checks_prefers_override_checks_to_configured_checks():
  29. checks = module.parse_checks(
  30. {'checks': [{'name': 'archives'}]}, only_checks=['repository', 'extract']
  31. )
  32. assert checks == ('repository', 'extract')
  33. @pytest.mark.parametrize(
  34. 'frequency,expected_result',
  35. (
  36. (None, None),
  37. ('always', None),
  38. ('1 hour', module.datetime.timedelta(hours=1)),
  39. ('2 hours', module.datetime.timedelta(hours=2)),
  40. ('1 day', module.datetime.timedelta(days=1)),
  41. ('2 days', module.datetime.timedelta(days=2)),
  42. ('1 week', module.datetime.timedelta(weeks=1)),
  43. ('2 weeks', module.datetime.timedelta(weeks=2)),
  44. ('1 month', module.datetime.timedelta(days=30)),
  45. ('2 months', module.datetime.timedelta(days=60)),
  46. ('1 year', module.datetime.timedelta(days=365)),
  47. ('2 years', module.datetime.timedelta(days=365 * 2)),
  48. ),
  49. )
  50. def test_parse_frequency_parses_into_timedeltas(frequency, expected_result):
  51. assert module.parse_frequency(frequency) == expected_result
  52. @pytest.mark.parametrize(
  53. 'frequency',
  54. (
  55. 'sometime',
  56. 'x days',
  57. '3 decades',
  58. ),
  59. )
  60. def test_parse_frequency_raises_on_parse_error(frequency):
  61. with pytest.raises(ValueError):
  62. module.parse_frequency(frequency)
  63. def test_filter_checks_on_frequency_without_config_uses_default_checks():
  64. flexmock(module).should_receive('parse_frequency').and_return(
  65. module.datetime.timedelta(weeks=4)
  66. )
  67. flexmock(module).should_receive('make_check_time_path')
  68. flexmock(module).should_receive('read_check_time').and_return(None)
  69. assert module.filter_checks_on_frequency(
  70. location_config={},
  71. consistency_config={},
  72. borg_repository_id='repo',
  73. checks=('repository', 'archives'),
  74. force=False,
  75. ) == ('repository', 'archives')
  76. def test_filter_checks_on_frequency_retains_unconfigured_check():
  77. assert module.filter_checks_on_frequency(
  78. location_config={},
  79. consistency_config={},
  80. borg_repository_id='repo',
  81. checks=('data',),
  82. force=False,
  83. ) == ('data',)
  84. def test_filter_checks_on_frequency_retains_check_without_frequency():
  85. flexmock(module).should_receive('parse_frequency').and_return(None)
  86. assert module.filter_checks_on_frequency(
  87. location_config={},
  88. consistency_config={'checks': [{'name': 'archives'}]},
  89. borg_repository_id='repo',
  90. checks=('archives',),
  91. force=False,
  92. ) == ('archives',)
  93. def test_filter_checks_on_frequency_retains_check_with_elapsed_frequency():
  94. flexmock(module).should_receive('parse_frequency').and_return(
  95. module.datetime.timedelta(hours=1)
  96. )
  97. flexmock(module).should_receive('make_check_time_path')
  98. flexmock(module).should_receive('read_check_time').and_return(
  99. module.datetime.datetime(year=module.datetime.MINYEAR, month=1, day=1)
  100. )
  101. assert module.filter_checks_on_frequency(
  102. location_config={},
  103. consistency_config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  104. borg_repository_id='repo',
  105. checks=('archives',),
  106. force=False,
  107. ) == ('archives',)
  108. def test_filter_checks_on_frequency_retains_check_with_missing_check_time_file():
  109. flexmock(module).should_receive('parse_frequency').and_return(
  110. module.datetime.timedelta(hours=1)
  111. )
  112. flexmock(module).should_receive('make_check_time_path')
  113. flexmock(module).should_receive('read_check_time').and_return(None)
  114. assert module.filter_checks_on_frequency(
  115. location_config={},
  116. consistency_config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  117. borg_repository_id='repo',
  118. checks=('archives',),
  119. force=False,
  120. ) == ('archives',)
  121. def test_filter_checks_on_frequency_skips_check_with_unelapsed_frequency():
  122. flexmock(module).should_receive('parse_frequency').and_return(
  123. module.datetime.timedelta(hours=1)
  124. )
  125. flexmock(module).should_receive('make_check_time_path')
  126. flexmock(module).should_receive('read_check_time').and_return(module.datetime.datetime.now())
  127. assert (
  128. module.filter_checks_on_frequency(
  129. location_config={},
  130. consistency_config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  131. borg_repository_id='repo',
  132. checks=('archives',),
  133. force=False,
  134. )
  135. == ()
  136. )
  137. def test_filter_checks_on_frequency_restains_check_with_unelapsed_frequency_and_force():
  138. assert module.filter_checks_on_frequency(
  139. location_config={},
  140. consistency_config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  141. borg_repository_id='repo',
  142. checks=('archives',),
  143. force=True,
  144. ) == ('archives',)
  145. def test_make_check_flags_with_repository_check_returns_flag():
  146. flexmock(module.feature).should_receive('available').and_return(True)
  147. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  148. flags = module.make_check_flags('1.2.3', {}, ('repository',))
  149. assert flags == ('--repository-only',)
  150. def test_make_check_flags_with_archives_check_returns_flag():
  151. flexmock(module.feature).should_receive('available').and_return(True)
  152. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  153. flags = module.make_check_flags('1.2.3', {}, ('archives',))
  154. assert flags == ('--archives-only',)
  155. def test_make_check_flags_with_data_check_returns_flag_and_implies_archives():
  156. flexmock(module.feature).should_receive('available').and_return(True)
  157. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  158. flags = module.make_check_flags('1.2.3', {}, ('data',))
  159. assert flags == (
  160. '--archives-only',
  161. '--verify-data',
  162. )
  163. def test_make_check_flags_with_extract_omits_extract_flag():
  164. flexmock(module.feature).should_receive('available').and_return(True)
  165. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  166. flags = module.make_check_flags('1.2.3', {}, ('extract',))
  167. assert flags == ()
  168. def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only():
  169. flexmock(module.feature).should_receive('available').and_return(True)
  170. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  171. flags = module.make_check_flags(
  172. '1.2.3',
  173. {},
  174. (
  175. 'repository',
  176. 'data',
  177. ),
  178. )
  179. assert flags == ('--verify-data',)
  180. def test_make_check_flags_with_default_checks_and_prefix_returns_default_flags():
  181. flexmock(module.feature).should_receive('available').and_return(True)
  182. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  183. flags = module.make_check_flags(
  184. '1.2.3',
  185. {},
  186. ('repository', 'archives'),
  187. prefix='foo',
  188. )
  189. assert flags == ('--match-archives', 'sh:foo*')
  190. def test_make_check_flags_with_all_checks_and_prefix_returns_default_flags():
  191. flexmock(module.feature).should_receive('available').and_return(True)
  192. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  193. flags = module.make_check_flags(
  194. '1.2.3',
  195. {},
  196. ('repository', 'archives', 'extract'),
  197. prefix='foo',
  198. )
  199. assert flags == ('--match-archives', 'sh:foo*')
  200. def test_make_check_flags_with_all_checks_and_prefix_without_borg_features_returns_glob_archives_flags():
  201. flexmock(module.feature).should_receive('available').and_return(False)
  202. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  203. flags = module.make_check_flags(
  204. '1.2.3',
  205. {},
  206. ('repository', 'archives', 'extract'),
  207. prefix='foo',
  208. )
  209. assert flags == ('--glob-archives', 'foo*')
  210. def test_make_check_flags_with_archives_check_and_last_includes_last_flag():
  211. flexmock(module.feature).should_receive('available').and_return(True)
  212. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  213. flags = module.make_check_flags('1.2.3', {}, ('archives',), check_last=3)
  214. assert flags == ('--archives-only', '--last', '3')
  215. def test_make_check_flags_with_data_check_and_last_includes_last_flag():
  216. flexmock(module.feature).should_receive('available').and_return(True)
  217. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  218. flags = module.make_check_flags('1.2.3', {}, ('data',), check_last=3)
  219. assert flags == ('--archives-only', '--last', '3', '--verify-data')
  220. def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
  221. flexmock(module.feature).should_receive('available').and_return(True)
  222. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  223. flags = module.make_check_flags('1.2.3', {}, ('repository',), check_last=3)
  224. assert flags == ('--repository-only',)
  225. def test_make_check_flags_with_default_checks_and_last_includes_last_flag():
  226. flexmock(module.feature).should_receive('available').and_return(True)
  227. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  228. flags = module.make_check_flags('1.2.3', {}, ('repository', 'archives'), check_last=3)
  229. assert flags == ('--last', '3')
  230. def test_make_check_flags_with_archives_check_and_prefix_includes_match_archives_flag():
  231. flexmock(module.feature).should_receive('available').and_return(True)
  232. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  233. flags = module.make_check_flags('1.2.3', {}, ('archives',), prefix='foo-')
  234. assert flags == ('--archives-only', '--match-archives', 'sh:foo-*')
  235. def test_make_check_flags_with_data_check_and_prefix_includes_match_archives_flag():
  236. flexmock(module.feature).should_receive('available').and_return(True)
  237. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  238. flags = module.make_check_flags('1.2.3', {}, ('data',), prefix='foo-')
  239. assert flags == ('--archives-only', '--match-archives', 'sh:foo-*', '--verify-data')
  240. def test_make_check_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead():
  241. flexmock(module.feature).should_receive('available').and_return(True)
  242. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  243. None, 'bar-{now}', '1.2.3' # noqa: FS003
  244. ).and_return(('--match-archives', 'sh:bar-*'))
  245. flags = module.make_check_flags(
  246. '1.2.3', {'archive_name_format': 'bar-{now}'}, ('archives',), prefix='' # noqa: FS003
  247. )
  248. assert flags == ('--archives-only', '--match-archives', 'sh:bar-*')
  249. def test_make_check_flags_with_archives_check_and_none_prefix_omits_match_archives_flag():
  250. flexmock(module.feature).should_receive('available').and_return(True)
  251. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  252. flags = module.make_check_flags('1.2.3', {}, ('archives',), prefix=None)
  253. assert flags == ('--archives-only',)
  254. def test_make_check_flags_with_repository_check_and_prefix_omits_match_archives_flag():
  255. flexmock(module.feature).should_receive('available').and_return(True)
  256. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  257. flags = module.make_check_flags('1.2.3', {}, ('repository',), prefix='foo-')
  258. assert flags == ('--repository-only',)
  259. def test_make_check_flags_with_default_checks_and_prefix_includes_match_archives_flag():
  260. flexmock(module.feature).should_receive('available').and_return(True)
  261. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  262. flags = module.make_check_flags('1.2.3', {}, ('repository', 'archives'), prefix='foo-')
  263. assert flags == ('--match-archives', 'sh:foo-*')
  264. def test_read_check_time_does_not_raise():
  265. flexmock(module.os).should_receive('stat').and_return(flexmock(st_mtime=123))
  266. assert module.read_check_time('/path')
  267. def test_read_check_time_on_missing_file_does_not_raise():
  268. flexmock(module.os).should_receive('stat').and_raise(FileNotFoundError)
  269. assert module.read_check_time('/path') is None
  270. def test_check_archives_with_progress_calls_borg_with_progress_parameter():
  271. checks = ('repository',)
  272. consistency_config = {'check_last': None}
  273. flexmock(module).should_receive('parse_checks')
  274. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  275. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  276. '{"repository": {"id": "repo"}}'
  277. )
  278. flexmock(module).should_receive('make_check_flags').and_return(())
  279. flexmock(module).should_receive('execute_command').never()
  280. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  281. flexmock(module.environment).should_receive('make_environment')
  282. flexmock(module).should_receive('execute_command').with_args(
  283. ('borg', 'check', '--progress', 'repo'),
  284. output_file=module.DO_NOT_CAPTURE,
  285. extra_environment=None,
  286. ).once()
  287. flexmock(module).should_receive('make_check_time_path')
  288. flexmock(module).should_receive('write_check_time')
  289. module.check_archives(
  290. repository_path='repo',
  291. location_config={},
  292. storage_config={},
  293. consistency_config=consistency_config,
  294. local_borg_version='1.2.3',
  295. global_arguments=flexmock(log_json=False),
  296. progress=True,
  297. )
  298. def test_check_archives_with_repair_calls_borg_with_repair_parameter():
  299. checks = ('repository',)
  300. consistency_config = {'check_last': None}
  301. flexmock(module).should_receive('parse_checks')
  302. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  303. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  304. '{"repository": {"id": "repo"}}'
  305. )
  306. flexmock(module).should_receive('make_check_flags').and_return(())
  307. flexmock(module).should_receive('execute_command').never()
  308. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  309. flexmock(module.environment).should_receive('make_environment')
  310. flexmock(module).should_receive('execute_command').with_args(
  311. ('borg', 'check', '--repair', 'repo'),
  312. output_file=module.DO_NOT_CAPTURE,
  313. extra_environment=None,
  314. ).once()
  315. flexmock(module).should_receive('make_check_time_path')
  316. flexmock(module).should_receive('write_check_time')
  317. module.check_archives(
  318. repository_path='repo',
  319. location_config={},
  320. storage_config={},
  321. consistency_config=consistency_config,
  322. local_borg_version='1.2.3',
  323. global_arguments=flexmock(log_json=False),
  324. repair=True,
  325. )
  326. @pytest.mark.parametrize(
  327. 'checks',
  328. (
  329. ('repository',),
  330. ('archives',),
  331. ('repository', 'archives'),
  332. ('repository', 'archives', 'other'),
  333. ),
  334. )
  335. def test_check_archives_calls_borg_with_parameters(checks):
  336. check_last = flexmock()
  337. consistency_config = {'check_last': check_last}
  338. flexmock(module).should_receive('parse_checks')
  339. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  340. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  341. '{"repository": {"id": "repo"}}'
  342. )
  343. flexmock(module).should_receive('make_check_flags').with_args(
  344. '1.2.3',
  345. {},
  346. checks,
  347. check_last,
  348. prefix=None,
  349. ).and_return(())
  350. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  351. insert_execute_command_mock(('borg', 'check', 'repo'))
  352. flexmock(module).should_receive('make_check_time_path')
  353. flexmock(module).should_receive('write_check_time')
  354. module.check_archives(
  355. repository_path='repo',
  356. location_config={},
  357. storage_config={},
  358. consistency_config=consistency_config,
  359. local_borg_version='1.2.3',
  360. global_arguments=flexmock(log_json=False),
  361. )
  362. def test_check_archives_with_json_error_raises():
  363. checks = ('archives',)
  364. check_last = flexmock()
  365. consistency_config = {'check_last': check_last}
  366. flexmock(module).should_receive('parse_checks')
  367. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  368. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  369. '{"unexpected": {"id": "repo"}}'
  370. )
  371. with pytest.raises(ValueError):
  372. module.check_archives(
  373. repository_path='repo',
  374. location_config={},
  375. storage_config={},
  376. consistency_config=consistency_config,
  377. local_borg_version='1.2.3',
  378. global_arguments=flexmock(log_json=False),
  379. )
  380. def test_check_archives_with_missing_json_keys_raises():
  381. checks = ('archives',)
  382. check_last = flexmock()
  383. consistency_config = {'check_last': check_last}
  384. flexmock(module).should_receive('parse_checks')
  385. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  386. flexmock(module.rinfo).should_receive('display_repository_info').and_return('{invalid JSON')
  387. with pytest.raises(ValueError):
  388. module.check_archives(
  389. repository_path='repo',
  390. location_config={},
  391. storage_config={},
  392. consistency_config=consistency_config,
  393. local_borg_version='1.2.3',
  394. global_arguments=flexmock(log_json=False),
  395. )
  396. def test_check_archives_with_extract_check_calls_extract_only():
  397. checks = ('extract',)
  398. check_last = flexmock()
  399. consistency_config = {'check_last': check_last}
  400. flexmock(module).should_receive('parse_checks')
  401. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  402. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  403. '{"repository": {"id": "repo"}}'
  404. )
  405. flexmock(module).should_receive('make_check_flags').never()
  406. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  407. flexmock(module.extract).should_receive('extract_last_archive_dry_run').once()
  408. flexmock(module).should_receive('write_check_time')
  409. insert_execute_command_never()
  410. module.check_archives(
  411. repository_path='repo',
  412. location_config={},
  413. storage_config={},
  414. consistency_config=consistency_config,
  415. local_borg_version='1.2.3',
  416. global_arguments=flexmock(log_json=False),
  417. )
  418. def test_check_archives_with_log_info_calls_borg_with_info_parameter():
  419. checks = ('repository',)
  420. consistency_config = {'check_last': None}
  421. flexmock(module).should_receive('parse_checks')
  422. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  423. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  424. '{"repository": {"id": "repo"}}'
  425. )
  426. flexmock(module).should_receive('make_check_flags').and_return(())
  427. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  428. insert_logging_mock(logging.INFO)
  429. insert_execute_command_mock(('borg', 'check', '--info', 'repo'))
  430. flexmock(module).should_receive('make_check_time_path')
  431. flexmock(module).should_receive('write_check_time')
  432. module.check_archives(
  433. repository_path='repo',
  434. location_config={},
  435. storage_config={},
  436. consistency_config=consistency_config,
  437. local_borg_version='1.2.3',
  438. global_arguments=flexmock(log_json=False),
  439. )
  440. def test_check_archives_with_log_debug_calls_borg_with_debug_parameter():
  441. checks = ('repository',)
  442. consistency_config = {'check_last': None}
  443. flexmock(module).should_receive('parse_checks')
  444. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  445. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  446. '{"repository": {"id": "repo"}}'
  447. )
  448. flexmock(module).should_receive('make_check_flags').and_return(())
  449. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  450. insert_logging_mock(logging.DEBUG)
  451. insert_execute_command_mock(('borg', 'check', '--debug', '--show-rc', 'repo'))
  452. flexmock(module).should_receive('make_check_time_path')
  453. flexmock(module).should_receive('write_check_time')
  454. module.check_archives(
  455. repository_path='repo',
  456. location_config={},
  457. storage_config={},
  458. consistency_config=consistency_config,
  459. local_borg_version='1.2.3',
  460. global_arguments=flexmock(log_json=False),
  461. )
  462. def test_check_archives_without_any_checks_bails():
  463. consistency_config = {'check_last': None}
  464. flexmock(module).should_receive('parse_checks')
  465. flexmock(module).should_receive('filter_checks_on_frequency').and_return(())
  466. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  467. '{"repository": {"id": "repo"}}'
  468. )
  469. insert_execute_command_never()
  470. module.check_archives(
  471. repository_path='repo',
  472. location_config={},
  473. storage_config={},
  474. consistency_config=consistency_config,
  475. local_borg_version='1.2.3',
  476. global_arguments=flexmock(log_json=False),
  477. )
  478. def test_check_archives_with_local_path_calls_borg_via_local_path():
  479. checks = ('repository',)
  480. check_last = flexmock()
  481. consistency_config = {'check_last': check_last}
  482. flexmock(module).should_receive('parse_checks')
  483. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  484. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  485. '{"repository": {"id": "repo"}}'
  486. )
  487. flexmock(module).should_receive('make_check_flags').with_args(
  488. '1.2.3',
  489. {},
  490. checks,
  491. check_last,
  492. prefix=None,
  493. ).and_return(())
  494. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  495. insert_execute_command_mock(('borg1', 'check', 'repo'))
  496. flexmock(module).should_receive('make_check_time_path')
  497. flexmock(module).should_receive('write_check_time')
  498. module.check_archives(
  499. repository_path='repo',
  500. location_config={},
  501. storage_config={},
  502. consistency_config=consistency_config,
  503. local_borg_version='1.2.3',
  504. global_arguments=flexmock(log_json=False),
  505. local_path='borg1',
  506. )
  507. def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters():
  508. checks = ('repository',)
  509. check_last = flexmock()
  510. consistency_config = {'check_last': check_last}
  511. flexmock(module).should_receive('parse_checks')
  512. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  513. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  514. '{"repository": {"id": "repo"}}'
  515. )
  516. flexmock(module).should_receive('make_check_flags').with_args(
  517. '1.2.3',
  518. {},
  519. checks,
  520. check_last,
  521. prefix=None,
  522. ).and_return(())
  523. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  524. insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo'))
  525. flexmock(module).should_receive('make_check_time_path')
  526. flexmock(module).should_receive('write_check_time')
  527. module.check_archives(
  528. repository_path='repo',
  529. location_config={},
  530. storage_config={},
  531. consistency_config=consistency_config,
  532. local_borg_version='1.2.3',
  533. global_arguments=flexmock(log_json=False),
  534. remote_path='borg1',
  535. )
  536. def test_check_archives_with_log_json_calls_borg_with_log_json_parameters():
  537. checks = ('repository',)
  538. check_last = flexmock()
  539. storage_config = {}
  540. consistency_config = {'check_last': check_last}
  541. flexmock(module).should_receive('parse_checks')
  542. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  543. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  544. '{"repository": {"id": "repo"}}'
  545. )
  546. flexmock(module).should_receive('make_check_flags').with_args(
  547. '1.2.3',
  548. storage_config,
  549. checks,
  550. check_last,
  551. None,
  552. ).and_return(())
  553. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  554. insert_execute_command_mock(('borg', 'check', '--log-json', 'repo'))
  555. flexmock(module).should_receive('make_check_time_path')
  556. flexmock(module).should_receive('write_check_time')
  557. module.check_archives(
  558. repository_path='repo',
  559. location_config={},
  560. storage_config=storage_config,
  561. consistency_config=consistency_config,
  562. local_borg_version='1.2.3',
  563. global_arguments=flexmock(log_json=True),
  564. )
  565. def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
  566. checks = ('repository',)
  567. check_last = flexmock()
  568. storage_config = {'lock_wait': 5}
  569. consistency_config = {'check_last': check_last}
  570. flexmock(module).should_receive('parse_checks')
  571. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  572. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  573. '{"repository": {"id": "repo"}}'
  574. )
  575. flexmock(module).should_receive('make_check_flags').with_args(
  576. '1.2.3',
  577. storage_config,
  578. checks,
  579. check_last,
  580. None,
  581. ).and_return(())
  582. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  583. insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo'))
  584. flexmock(module).should_receive('make_check_time_path')
  585. flexmock(module).should_receive('write_check_time')
  586. module.check_archives(
  587. repository_path='repo',
  588. location_config={},
  589. storage_config=storage_config,
  590. consistency_config=consistency_config,
  591. local_borg_version='1.2.3',
  592. global_arguments=flexmock(log_json=False),
  593. )
  594. def test_check_archives_with_retention_prefix():
  595. checks = ('repository',)
  596. check_last = flexmock()
  597. prefix = 'foo-'
  598. consistency_config = {'check_last': check_last, 'prefix': prefix}
  599. flexmock(module).should_receive('parse_checks')
  600. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  601. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  602. '{"repository": {"id": "repo"}}'
  603. )
  604. flexmock(module).should_receive('make_check_flags').with_args(
  605. '1.2.3', {}, checks, check_last, prefix
  606. ).and_return(())
  607. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  608. insert_execute_command_mock(('borg', 'check', 'repo'))
  609. flexmock(module).should_receive('make_check_time_path')
  610. flexmock(module).should_receive('write_check_time')
  611. module.check_archives(
  612. repository_path='repo',
  613. location_config={},
  614. storage_config={},
  615. consistency_config=consistency_config,
  616. local_borg_version='1.2.3',
  617. global_arguments=flexmock(log_json=False),
  618. )
  619. def test_check_archives_with_extra_borg_options_calls_borg_with_extra_options():
  620. checks = ('repository',)
  621. consistency_config = {'check_last': None}
  622. flexmock(module).should_receive('parse_checks')
  623. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  624. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  625. '{"repository": {"id": "repo"}}'
  626. )
  627. flexmock(module).should_receive('make_check_flags').and_return(())
  628. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  629. insert_execute_command_mock(('borg', 'check', '--extra', '--options', 'repo'))
  630. flexmock(module).should_receive('make_check_time_path')
  631. flexmock(module).should_receive('write_check_time')
  632. module.check_archives(
  633. repository_path='repo',
  634. location_config={},
  635. storage_config={'extra_borg_options': {'check': '--extra --options'}},
  636. consistency_config=consistency_config,
  637. local_borg_version='1.2.3',
  638. global_arguments=flexmock(log_json=False),
  639. )