test_check.py 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  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(
  7. command, output_file=None, working_directory=None, borg_exit_codes=None
  8. ):
  9. flexmock(module.environment).should_receive('make_environment')
  10. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
  11. working_directory,
  12. )
  13. flexmock(module).should_receive('execute_command').with_args(
  14. command,
  15. output_file=output_file,
  16. extra_environment=None,
  17. working_directory=working_directory,
  18. borg_local_path=command[0],
  19. borg_exit_codes=borg_exit_codes,
  20. ).once()
  21. def insert_execute_command_never():
  22. flexmock(module).should_receive('execute_command').never()
  23. def test_make_archive_filter_flags_with_default_checks_and_prefix_returns_default_flags():
  24. flexmock(module.feature).should_receive('available').and_return(True)
  25. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  26. flags = module.make_archive_filter_flags(
  27. '1.2.3',
  28. {'prefix': 'foo'},
  29. ('repository', 'archives'),
  30. check_arguments=flexmock(match_archives=None),
  31. )
  32. assert flags == ('--match-archives', 'sh:foo*')
  33. def test_make_archive_filter_flags_with_all_checks_and_prefix_returns_default_flags():
  34. flexmock(module.feature).should_receive('available').and_return(True)
  35. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  36. flags = module.make_archive_filter_flags(
  37. '1.2.3',
  38. {'prefix': 'foo'},
  39. ('repository', 'archives', 'extract'),
  40. check_arguments=flexmock(match_archives=None),
  41. )
  42. assert flags == ('--match-archives', 'sh:foo*')
  43. def test_make_archive_filter_flags_with_all_checks_and_prefix_without_borg_features_returns_glob_archives_flags():
  44. flexmock(module.feature).should_receive('available').and_return(False)
  45. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  46. flags = module.make_archive_filter_flags(
  47. '1.2.3',
  48. {'prefix': 'foo'},
  49. ('repository', 'archives', 'extract'),
  50. check_arguments=flexmock(match_archives=None),
  51. )
  52. assert flags == ('--glob-archives', 'foo*')
  53. def test_make_archive_filter_flags_with_archives_check_and_last_includes_last_flag():
  54. flexmock(module.feature).should_receive('available').and_return(True)
  55. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  56. flags = module.make_archive_filter_flags(
  57. '1.2.3',
  58. {'check_last': 3},
  59. ('archives',),
  60. check_arguments=flexmock(match_archives=None),
  61. )
  62. assert flags == ('--last', '3')
  63. def test_make_archive_filter_flags_with_data_check_and_last_includes_last_flag():
  64. flexmock(module.feature).should_receive('available').and_return(True)
  65. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  66. flags = module.make_archive_filter_flags(
  67. '1.2.3',
  68. {'check_last': 3},
  69. ('data',),
  70. check_arguments=flexmock(match_archives=None),
  71. )
  72. assert flags == ('--last', '3')
  73. def test_make_archive_filter_flags_with_repository_check_and_last_omits_last_flag():
  74. flexmock(module.feature).should_receive('available').and_return(True)
  75. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  76. flags = module.make_archive_filter_flags(
  77. '1.2.3',
  78. {'check_last': 3},
  79. ('repository',),
  80. check_arguments=flexmock(match_archives=None),
  81. )
  82. assert flags == ()
  83. def test_make_archive_filter_flags_with_default_checks_and_last_includes_last_flag():
  84. flexmock(module.feature).should_receive('available').and_return(True)
  85. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  86. flags = module.make_archive_filter_flags(
  87. '1.2.3',
  88. {'check_last': 3},
  89. ('repository', 'archives'),
  90. check_arguments=flexmock(match_archives=None),
  91. )
  92. assert flags == ('--last', '3')
  93. def test_make_archive_filter_flags_with_archives_check_and_prefix_includes_match_archives_flag():
  94. flexmock(module.feature).should_receive('available').and_return(True)
  95. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  96. flags = module.make_archive_filter_flags(
  97. '1.2.3',
  98. {'prefix': 'foo-'},
  99. ('archives',),
  100. check_arguments=flexmock(match_archives=None),
  101. )
  102. assert flags == ('--match-archives', 'sh:foo-*')
  103. def test_make_archive_filter_flags_with_data_check_and_prefix_includes_match_archives_flag():
  104. flexmock(module.feature).should_receive('available').and_return(True)
  105. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  106. flags = module.make_archive_filter_flags(
  107. '1.2.3',
  108. {'prefix': 'foo-'},
  109. ('data',),
  110. check_arguments=flexmock(match_archives=None),
  111. )
  112. assert flags == ('--match-archives', 'sh:foo-*')
  113. def test_make_archive_filter_flags_prefers_check_arguments_match_archives_to_config_match_archives():
  114. flexmock(module.feature).should_receive('available').and_return(True)
  115. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  116. 'baz-*', None, '1.2.3'
  117. ).and_return(('--match-archives', 'sh:baz-*'))
  118. flags = module.make_archive_filter_flags(
  119. '1.2.3',
  120. {'match_archives': 'bar-{now}', 'prefix': ''}, # noqa: FS003
  121. ('archives',),
  122. check_arguments=flexmock(match_archives='baz-*'),
  123. )
  124. assert flags == ('--match-archives', 'sh:baz-*')
  125. def test_make_archive_filter_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead():
  126. flexmock(module.feature).should_receive('available').and_return(True)
  127. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  128. None, 'bar-{now}', '1.2.3' # noqa: FS003
  129. ).and_return(('--match-archives', 'sh:bar-*'))
  130. flags = module.make_archive_filter_flags(
  131. '1.2.3',
  132. {'archive_name_format': 'bar-{now}', 'prefix': ''}, # noqa: FS003
  133. ('archives',),
  134. check_arguments=flexmock(match_archives=None),
  135. )
  136. assert flags == ('--match-archives', 'sh:bar-*')
  137. def test_make_archive_filter_flags_with_archives_check_and_none_prefix_omits_match_archives_flag():
  138. flexmock(module.feature).should_receive('available').and_return(True)
  139. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  140. flags = module.make_archive_filter_flags(
  141. '1.2.3',
  142. {},
  143. ('archives',),
  144. check_arguments=flexmock(match_archives=None),
  145. )
  146. assert flags == ()
  147. def test_make_archive_filter_flags_with_repository_check_and_prefix_omits_match_archives_flag():
  148. flexmock(module.feature).should_receive('available').and_return(True)
  149. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  150. flags = module.make_archive_filter_flags(
  151. '1.2.3',
  152. {'prefix': 'foo-'},
  153. ('repository',),
  154. check_arguments=flexmock(match_archives=None),
  155. )
  156. assert flags == ()
  157. def test_make_archive_filter_flags_with_default_checks_and_prefix_includes_match_archives_flag():
  158. flexmock(module.feature).should_receive('available').and_return(True)
  159. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  160. flags = module.make_archive_filter_flags(
  161. '1.2.3',
  162. {'prefix': 'foo-'},
  163. ('repository', 'archives'),
  164. check_arguments=flexmock(match_archives=None),
  165. )
  166. assert flags == ('--match-archives', 'sh:foo-*')
  167. def test_make_check_name_flags_with_repository_check_returns_flag():
  168. flags = module.make_check_name_flags({'repository'}, ())
  169. assert flags == ('--repository-only',)
  170. def test_make_check_name_flags_with_archives_check_returns_flag():
  171. flags = module.make_check_name_flags({'archives'}, ())
  172. assert flags == ('--archives-only',)
  173. def test_make_check_name_flags_with_archives_check_and_archive_filter_flags_includes_those_flags():
  174. flags = module.make_check_name_flags({'archives'}, ('--match-archives', 'sh:foo-*'))
  175. assert flags == ('--archives-only', '--match-archives', 'sh:foo-*')
  176. def test_make_check_name_flags_without_archives_check_and_with_archive_filter_flags_includes_those_flags():
  177. flags = module.make_check_name_flags({'repository'}, ('--match-archives', 'sh:foo-*'))
  178. assert flags == ('--repository-only',)
  179. def test_make_check_name_flags_with_archives_and_data_check_returns_verify_data_flag():
  180. flexmock(module.feature).should_receive('available').and_return(True)
  181. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  182. flags = module.make_check_name_flags({'archives', 'data'}, ())
  183. assert flags == (
  184. '--archives-only',
  185. '--verify-data',
  186. )
  187. def test_make_check_name_flags_with_repository_and_data_check_returns_verify_data_flag():
  188. flexmock(module.feature).should_receive('available').and_return(True)
  189. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  190. flags = module.make_check_name_flags({'archives', 'data', 'repository'}, ())
  191. assert flags == ('--verify-data',)
  192. def test_make_check_name_flags_with_extract_omits_extract_flag():
  193. flexmock(module.feature).should_receive('available').and_return(True)
  194. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  195. flags = module.make_check_name_flags({'extract'}, ())
  196. assert flags == ()
  197. def test_get_repository_id_with_valid_json_does_not_raise():
  198. config = {}
  199. flexmock(module.repo_info).should_receive('display_repository_info').and_return(
  200. '{"repository": {"id": "repo"}}'
  201. )
  202. assert module.get_repository_id(
  203. repository_path='repo',
  204. config=config,
  205. local_borg_version='1.2.3',
  206. global_arguments=flexmock(log_json=False),
  207. local_path='borg',
  208. remote_path=None,
  209. )
  210. def test_get_repository_id_with_json_error_raises():
  211. config = {}
  212. flexmock(module.repo_info).should_receive('display_repository_info').and_return(
  213. '{"unexpected": {"id": "repo"}}'
  214. )
  215. with pytest.raises(ValueError):
  216. module.get_repository_id(
  217. repository_path='repo',
  218. config=config,
  219. local_borg_version='1.2.3',
  220. global_arguments=flexmock(log_json=False),
  221. local_path='borg',
  222. remote_path=None,
  223. )
  224. def test_get_repository_id_with_missing_json_keys_raises():
  225. config = {}
  226. flexmock(module.repo_info).should_receive('display_repository_info').and_return('{invalid JSON')
  227. with pytest.raises(ValueError):
  228. module.get_repository_id(
  229. repository_path='repo',
  230. config=config,
  231. local_borg_version='1.2.3',
  232. global_arguments=flexmock(log_json=False),
  233. local_path='borg',
  234. remote_path=None,
  235. )
  236. def test_check_archives_with_progress_passes_through_to_borg():
  237. config = {}
  238. flexmock(module).should_receive('make_check_name_flags').with_args(
  239. {'repository'}, ()
  240. ).and_return(())
  241. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  242. flexmock(module.environment).should_receive('make_environment')
  243. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  244. flexmock(module).should_receive('execute_command').with_args(
  245. ('borg', 'check', '--progress', 'repo'),
  246. output_file=module.DO_NOT_CAPTURE,
  247. extra_environment=None,
  248. working_directory=None,
  249. borg_local_path='borg',
  250. borg_exit_codes=None,
  251. ).once()
  252. module.check_archives(
  253. repository_path='repo',
  254. config=config,
  255. local_borg_version='1.2.3',
  256. check_arguments=flexmock(
  257. progress=True,
  258. repair=None,
  259. only_checks=None,
  260. force=None,
  261. match_archives=None,
  262. max_duration=None,
  263. ),
  264. global_arguments=flexmock(log_json=False),
  265. checks={'repository'},
  266. archive_filter_flags=(),
  267. )
  268. def test_check_archives_with_repair_passes_through_to_borg():
  269. config = {}
  270. flexmock(module).should_receive('make_check_name_flags').with_args(
  271. {'repository'}, ()
  272. ).and_return(())
  273. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  274. flexmock(module.environment).should_receive('make_environment')
  275. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  276. flexmock(module).should_receive('execute_command').with_args(
  277. ('borg', 'check', '--repair', 'repo'),
  278. output_file=module.DO_NOT_CAPTURE,
  279. extra_environment=None,
  280. working_directory=None,
  281. borg_local_path='borg',
  282. borg_exit_codes=None,
  283. ).once()
  284. module.check_archives(
  285. repository_path='repo',
  286. config=config,
  287. local_borg_version='1.2.3',
  288. check_arguments=flexmock(
  289. progress=None,
  290. repair=True,
  291. only_checks=None,
  292. force=None,
  293. match_archives=None,
  294. max_duration=None,
  295. ),
  296. global_arguments=flexmock(log_json=False),
  297. checks={'repository'},
  298. archive_filter_flags=(),
  299. )
  300. def test_check_archives_with_max_duration_flag_passes_through_to_borg():
  301. config = {}
  302. flexmock(module).should_receive('make_check_name_flags').with_args(
  303. {'repository'}, ()
  304. ).and_return(())
  305. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  306. flexmock(module.environment).should_receive('make_environment')
  307. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  308. flexmock(module).should_receive('execute_command').with_args(
  309. ('borg', 'check', '--max-duration', '33', 'repo'),
  310. output_file=None,
  311. extra_environment=None,
  312. working_directory=None,
  313. borg_local_path='borg',
  314. borg_exit_codes=None,
  315. ).once()
  316. module.check_archives(
  317. repository_path='repo',
  318. config=config,
  319. local_borg_version='1.2.3',
  320. check_arguments=flexmock(
  321. progress=None,
  322. repair=None,
  323. only_checks=None,
  324. force=None,
  325. match_archives=None,
  326. max_duration=33,
  327. ),
  328. global_arguments=flexmock(log_json=False),
  329. checks={'repository'},
  330. archive_filter_flags=(),
  331. )
  332. def test_check_archives_with_max_duration_option_passes_through_to_borg():
  333. config = {'checks': [{'name': 'repository', 'max_duration': 33}]}
  334. flexmock(module).should_receive('make_check_name_flags').with_args(
  335. {'repository'}, ()
  336. ).and_return(())
  337. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  338. flexmock(module.environment).should_receive('make_environment')
  339. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  340. flexmock(module).should_receive('execute_command').with_args(
  341. ('borg', 'check', '--max-duration', '33', 'repo'),
  342. output_file=None,
  343. extra_environment=None,
  344. working_directory=None,
  345. borg_local_path='borg',
  346. borg_exit_codes=None,
  347. ).once()
  348. module.check_archives(
  349. repository_path='repo',
  350. config=config,
  351. local_borg_version='1.2.3',
  352. check_arguments=flexmock(
  353. progress=None,
  354. repair=None,
  355. only_checks=None,
  356. force=None,
  357. match_archives=None,
  358. max_duration=None,
  359. ),
  360. global_arguments=flexmock(log_json=False),
  361. checks={'repository'},
  362. archive_filter_flags=(),
  363. )
  364. def test_check_archives_with_max_duration_option_and_archives_check_runs_repository_check_separately():
  365. config = {'checks': [{'name': 'repository', 'max_duration': 33}, {'name': 'archives'}]}
  366. flexmock(module).should_receive('make_check_name_flags').with_args({'archives'}, ()).and_return(
  367. ('--archives-only',)
  368. )
  369. flexmock(module).should_receive('make_check_name_flags').with_args(
  370. {'repository'}, ()
  371. ).and_return(('--repository-only',))
  372. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  373. insert_execute_command_mock(('borg', 'check', '--archives-only', 'repo'))
  374. insert_execute_command_mock(
  375. ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo')
  376. )
  377. module.check_archives(
  378. repository_path='repo',
  379. config=config,
  380. local_borg_version='1.2.3',
  381. check_arguments=flexmock(
  382. progress=None,
  383. repair=None,
  384. only_checks=None,
  385. force=None,
  386. match_archives=None,
  387. max_duration=None,
  388. ),
  389. global_arguments=flexmock(log_json=False),
  390. checks={'repository', 'archives'},
  391. archive_filter_flags=(),
  392. )
  393. def test_check_archives_with_max_duration_flag_and_archives_check_runs_repository_check_separately():
  394. config = {'checks': [{'name': 'repository'}, {'name': 'archives'}]}
  395. flexmock(module).should_receive('make_check_name_flags').with_args({'archives'}, ()).and_return(
  396. ('--archives-only',)
  397. )
  398. flexmock(module).should_receive('make_check_name_flags').with_args(
  399. {'repository'}, ()
  400. ).and_return(('--repository-only',))
  401. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  402. insert_execute_command_mock(('borg', 'check', '--archives-only', 'repo'))
  403. insert_execute_command_mock(
  404. ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo')
  405. )
  406. module.check_archives(
  407. repository_path='repo',
  408. config=config,
  409. local_borg_version='1.2.3',
  410. check_arguments=flexmock(
  411. progress=None,
  412. repair=None,
  413. only_checks=None,
  414. force=None,
  415. match_archives=None,
  416. max_duration=33,
  417. ),
  418. global_arguments=flexmock(log_json=False),
  419. checks={'repository', 'archives'},
  420. archive_filter_flags=(),
  421. )
  422. def test_check_archives_with_max_duration_option_and_data_check_runs_repository_check_separately():
  423. config = {'checks': [{'name': 'repository', 'max_duration': 33}, {'name': 'data'}]}
  424. flexmock(module).should_receive('make_check_name_flags').with_args(
  425. {'data', 'archives'}, ()
  426. ).and_return(('--archives-only', '--verify-data'))
  427. flexmock(module).should_receive('make_check_name_flags').with_args(
  428. {'repository'}, ()
  429. ).and_return(('--repository-only',))
  430. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  431. insert_execute_command_mock(('borg', 'check', '--archives-only', '--verify-data', 'repo'))
  432. insert_execute_command_mock(
  433. ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo')
  434. )
  435. module.check_archives(
  436. repository_path='repo',
  437. config=config,
  438. local_borg_version='1.2.3',
  439. check_arguments=flexmock(
  440. progress=None,
  441. repair=None,
  442. only_checks=None,
  443. force=None,
  444. match_archives=None,
  445. max_duration=None,
  446. ),
  447. global_arguments=flexmock(log_json=False),
  448. checks={'repository', 'data'},
  449. archive_filter_flags=(),
  450. )
  451. def test_check_archives_with_max_duration_flag_and_data_check_runs_repository_check_separately():
  452. config = {'checks': [{'name': 'repository'}, {'name': 'data'}]}
  453. flexmock(module).should_receive('make_check_name_flags').with_args(
  454. {'data', 'archives'}, ()
  455. ).and_return(('--archives-only', '--verify-data'))
  456. flexmock(module).should_receive('make_check_name_flags').with_args(
  457. {'repository'}, ()
  458. ).and_return(('--repository-only',))
  459. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  460. insert_execute_command_mock(('borg', 'check', '--archives-only', '--verify-data', 'repo'))
  461. insert_execute_command_mock(
  462. ('borg', 'check', '--max-duration', '33', '--repository-only', 'repo')
  463. )
  464. module.check_archives(
  465. repository_path='repo',
  466. config=config,
  467. local_borg_version='1.2.3',
  468. check_arguments=flexmock(
  469. progress=None,
  470. repair=None,
  471. only_checks=None,
  472. force=None,
  473. match_archives=None,
  474. max_duration=33,
  475. ),
  476. global_arguments=flexmock(log_json=False),
  477. checks={'repository', 'data'},
  478. archive_filter_flags=(),
  479. )
  480. def test_check_archives_with_max_duration_flag_overrides_max_duration_option():
  481. config = {'checks': [{'name': 'repository', 'max_duration': 33}]}
  482. flexmock(module).should_receive('make_check_name_flags').with_args(
  483. {'repository'}, ()
  484. ).and_return(())
  485. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  486. flexmock(module.environment).should_receive('make_environment')
  487. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  488. flexmock(module).should_receive('execute_command').with_args(
  489. ('borg', 'check', '--max-duration', '44', 'repo'),
  490. output_file=None,
  491. extra_environment=None,
  492. working_directory=None,
  493. borg_local_path='borg',
  494. borg_exit_codes=None,
  495. ).once()
  496. module.check_archives(
  497. repository_path='repo',
  498. config=config,
  499. local_borg_version='1.2.3',
  500. check_arguments=flexmock(
  501. progress=None,
  502. repair=None,
  503. only_checks=None,
  504. force=None,
  505. match_archives=None,
  506. max_duration=44,
  507. ),
  508. global_arguments=flexmock(log_json=False),
  509. checks={'repository'},
  510. archive_filter_flags=(),
  511. )
  512. @pytest.mark.parametrize(
  513. 'checks',
  514. (
  515. ('repository',),
  516. ('archives',),
  517. ('repository', 'archives'),
  518. ('repository', 'archives', 'other'),
  519. ),
  520. )
  521. def test_check_archives_calls_borg_with_parameters(checks):
  522. config = {}
  523. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  524. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  525. insert_execute_command_mock(('borg', 'check', 'repo'))
  526. module.check_archives(
  527. repository_path='repo',
  528. config=config,
  529. local_borg_version='1.2.3',
  530. check_arguments=flexmock(
  531. progress=None,
  532. repair=None,
  533. only_checks=None,
  534. force=None,
  535. match_archives=None,
  536. max_duration=None,
  537. ),
  538. global_arguments=flexmock(log_json=False),
  539. checks=checks,
  540. archive_filter_flags=(),
  541. )
  542. def test_check_archives_with_data_check_implies_archives_check_calls_borg_with_parameters():
  543. config = {}
  544. flexmock(module).should_receive('make_check_name_flags').with_args(
  545. {'data', 'archives'}, ()
  546. ).and_return(())
  547. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  548. insert_execute_command_mock(('borg', 'check', 'repo'))
  549. module.check_archives(
  550. repository_path='repo',
  551. config=config,
  552. local_borg_version='1.2.3',
  553. check_arguments=flexmock(
  554. progress=None,
  555. repair=None,
  556. only_checks=None,
  557. force=None,
  558. match_archives=None,
  559. max_duration=None,
  560. ),
  561. global_arguments=flexmock(log_json=False),
  562. checks={'data'},
  563. archive_filter_flags=(),
  564. )
  565. def test_check_archives_with_log_info_passes_through_to_borg():
  566. config = {}
  567. flexmock(module).should_receive('make_check_name_flags').with_args(
  568. {'repository'}, ()
  569. ).and_return(())
  570. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  571. insert_logging_mock(logging.INFO)
  572. insert_execute_command_mock(('borg', 'check', '--info', 'repo'))
  573. module.check_archives(
  574. repository_path='repo',
  575. config=config,
  576. local_borg_version='1.2.3',
  577. check_arguments=flexmock(
  578. progress=None,
  579. repair=None,
  580. only_checks=None,
  581. force=None,
  582. match_archives=None,
  583. max_duration=None,
  584. ),
  585. global_arguments=flexmock(log_json=False),
  586. checks={'repository'},
  587. archive_filter_flags=(),
  588. )
  589. def test_check_archives_with_log_debug_passes_through_to_borg():
  590. config = {}
  591. flexmock(module).should_receive('make_check_name_flags').with_args(
  592. {'repository'}, ()
  593. ).and_return(())
  594. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  595. insert_logging_mock(logging.DEBUG)
  596. insert_execute_command_mock(('borg', 'check', '--debug', '--show-rc', 'repo'))
  597. module.check_archives(
  598. repository_path='repo',
  599. config=config,
  600. local_borg_version='1.2.3',
  601. check_arguments=flexmock(
  602. progress=None,
  603. repair=None,
  604. only_checks=None,
  605. force=None,
  606. match_archives=None,
  607. max_duration=None,
  608. ),
  609. global_arguments=flexmock(log_json=False),
  610. checks={'repository'},
  611. archive_filter_flags=(),
  612. )
  613. def test_check_archives_with_local_path_calls_borg_via_local_path():
  614. checks = {'repository'}
  615. config = {}
  616. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  617. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  618. insert_execute_command_mock(('borg1', 'check', 'repo'))
  619. module.check_archives(
  620. repository_path='repo',
  621. config=config,
  622. local_borg_version='1.2.3',
  623. check_arguments=flexmock(
  624. progress=None,
  625. repair=None,
  626. only_checks=None,
  627. force=None,
  628. match_archives=None,
  629. max_duration=None,
  630. ),
  631. global_arguments=flexmock(log_json=False),
  632. checks=checks,
  633. archive_filter_flags=(),
  634. local_path='borg1',
  635. )
  636. def test_check_archives_with_exit_codes_calls_borg_using_them():
  637. checks = {'repository'}
  638. borg_exit_codes = flexmock()
  639. config = {'borg_exit_codes': borg_exit_codes}
  640. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  641. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  642. insert_execute_command_mock(('borg', 'check', 'repo'), borg_exit_codes=borg_exit_codes)
  643. module.check_archives(
  644. repository_path='repo',
  645. config=config,
  646. local_borg_version='1.2.3',
  647. check_arguments=flexmock(
  648. progress=None,
  649. repair=None,
  650. only_checks=None,
  651. force=None,
  652. match_archives=None,
  653. max_duration=None,
  654. ),
  655. global_arguments=flexmock(log_json=False),
  656. checks=checks,
  657. archive_filter_flags=(),
  658. )
  659. def test_check_archives_with_remote_path_passes_through_to_borg():
  660. checks = {'repository'}
  661. config = {}
  662. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  663. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  664. insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo'))
  665. module.check_archives(
  666. repository_path='repo',
  667. config=config,
  668. local_borg_version='1.2.3',
  669. check_arguments=flexmock(
  670. progress=None,
  671. repair=None,
  672. only_checks=None,
  673. force=None,
  674. match_archives=None,
  675. max_duration=None,
  676. ),
  677. global_arguments=flexmock(log_json=False),
  678. checks=checks,
  679. archive_filter_flags=(),
  680. remote_path='borg1',
  681. )
  682. def test_check_archives_with_umask_passes_through_to_borg():
  683. checks = {'repository'}
  684. config = {'umask': '077'}
  685. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  686. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  687. insert_execute_command_mock(('borg', 'check', '--umask', '077', 'repo'))
  688. module.check_archives(
  689. repository_path='repo',
  690. config=config,
  691. local_borg_version='1.2.3',
  692. check_arguments=flexmock(
  693. progress=None,
  694. repair=None,
  695. only_checks=None,
  696. force=None,
  697. match_archives=None,
  698. max_duration=None,
  699. ),
  700. global_arguments=flexmock(log_json=False),
  701. checks=checks,
  702. archive_filter_flags=(),
  703. )
  704. def test_check_archives_with_log_json_passes_through_to_borg():
  705. checks = {'repository'}
  706. config = {}
  707. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  708. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  709. insert_execute_command_mock(('borg', 'check', '--log-json', 'repo'))
  710. module.check_archives(
  711. repository_path='repo',
  712. config=config,
  713. local_borg_version='1.2.3',
  714. check_arguments=flexmock(
  715. progress=None,
  716. repair=None,
  717. only_checks=None,
  718. force=None,
  719. match_archives=None,
  720. max_duration=None,
  721. ),
  722. global_arguments=flexmock(log_json=True),
  723. checks=checks,
  724. archive_filter_flags=(),
  725. )
  726. def test_check_archives_with_lock_wait_passes_through_to_borg():
  727. checks = {'repository'}
  728. config = {'lock_wait': 5}
  729. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  730. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  731. insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo'))
  732. module.check_archives(
  733. repository_path='repo',
  734. config=config,
  735. local_borg_version='1.2.3',
  736. check_arguments=flexmock(
  737. progress=None,
  738. repair=None,
  739. only_checks=None,
  740. force=None,
  741. match_archives=None,
  742. max_duration=None,
  743. ),
  744. global_arguments=flexmock(log_json=False),
  745. checks=checks,
  746. archive_filter_flags=(),
  747. )
  748. def test_check_archives_with_retention_prefix():
  749. checks = {'repository'}
  750. prefix = 'foo-'
  751. config = {'prefix': prefix}
  752. flexmock(module).should_receive('make_check_name_flags').with_args(checks, ()).and_return(())
  753. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  754. insert_execute_command_mock(('borg', 'check', 'repo'))
  755. module.check_archives(
  756. repository_path='repo',
  757. config=config,
  758. local_borg_version='1.2.3',
  759. check_arguments=flexmock(
  760. progress=None,
  761. repair=None,
  762. only_checks=None,
  763. force=None,
  764. match_archives=None,
  765. max_duration=None,
  766. ),
  767. global_arguments=flexmock(log_json=False),
  768. checks=checks,
  769. archive_filter_flags=(),
  770. )
  771. def test_check_archives_with_extra_borg_options_passes_through_to_borg():
  772. config = {'extra_borg_options': {'check': '--extra --options'}}
  773. flexmock(module).should_receive('make_check_name_flags').with_args(
  774. {'repository'}, ()
  775. ).and_return(())
  776. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  777. insert_execute_command_mock(('borg', 'check', '--extra', '--options', 'repo'))
  778. module.check_archives(
  779. repository_path='repo',
  780. config=config,
  781. local_borg_version='1.2.3',
  782. check_arguments=flexmock(
  783. progress=None,
  784. repair=None,
  785. only_checks=None,
  786. force=None,
  787. match_archives=None,
  788. max_duration=None,
  789. ),
  790. global_arguments=flexmock(log_json=False),
  791. checks={'repository'},
  792. archive_filter_flags=(),
  793. )
  794. def test_check_archives_with_match_archives_passes_through_to_borg():
  795. config = {'checks': [{'name': 'archives'}]}
  796. flexmock(module).should_receive('make_check_name_flags').with_args(
  797. {'archives'}, object
  798. ).and_return(('--match-archives', 'foo-*'))
  799. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  800. flexmock(module.environment).should_receive('make_environment')
  801. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  802. flexmock(module).should_receive('execute_command').with_args(
  803. ('borg', 'check', '--match-archives', 'foo-*', 'repo'),
  804. output_file=None,
  805. extra_environment=None,
  806. working_directory=None,
  807. borg_local_path='borg',
  808. borg_exit_codes=None,
  809. ).once()
  810. module.check_archives(
  811. repository_path='repo',
  812. config=config,
  813. local_borg_version='1.2.3',
  814. check_arguments=flexmock(
  815. progress=None,
  816. repair=None,
  817. only_checks=None,
  818. force=None,
  819. match_archives='foo-*',
  820. max_duration=None,
  821. ),
  822. global_arguments=flexmock(log_json=False),
  823. checks={'archives'},
  824. archive_filter_flags=('--match-archives', 'foo-*'),
  825. )
  826. def test_check_archives_calls_borg_with_working_directory():
  827. config = {'working_directory': '/working/dir'}
  828. flexmock(module).should_receive('make_check_name_flags').with_args(
  829. {'repository'}, ()
  830. ).and_return(())
  831. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  832. flexmock(module.environment).should_receive('make_environment')
  833. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  834. insert_execute_command_mock(('borg', 'check', 'repo'), working_directory='/working/dir')
  835. module.check_archives(
  836. repository_path='repo',
  837. config=config,
  838. local_borg_version='1.2.3',
  839. check_arguments=flexmock(
  840. progress=False,
  841. repair=None,
  842. only_checks=None,
  843. force=None,
  844. match_archives=None,
  845. max_duration=None,
  846. ),
  847. global_arguments=flexmock(log_json=False),
  848. checks={'repository'},
  849. archive_filter_flags=(),
  850. )