test_check.py 33 KB

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