test_check.py 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  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, borg_exit_codes=None):
  7. flexmock(module.environment).should_receive('make_environment')
  8. flexmock(module).should_receive('execute_command').with_args(
  9. command,
  10. extra_environment=None,
  11. borg_local_path=command[0],
  12. borg_exit_codes=borg_exit_codes,
  13. ).once()
  14. def insert_execute_command_never():
  15. flexmock(module).should_receive('execute_command').never()
  16. def test_parse_checks_returns_them_as_tuple():
  17. checks = module.parse_checks({'checks': [{'name': 'foo'}, {'name': 'bar'}]})
  18. assert checks == ('foo', 'bar')
  19. def test_parse_checks_with_missing_value_returns_defaults():
  20. checks = module.parse_checks({})
  21. assert checks == ('repository', 'archives')
  22. def test_parse_checks_with_empty_list_returns_defaults():
  23. checks = module.parse_checks({'checks': []})
  24. assert checks == ('repository', 'archives')
  25. def test_parse_checks_with_none_value_returns_defaults():
  26. checks = module.parse_checks({'checks': None})
  27. assert checks == ('repository', 'archives')
  28. def test_parse_checks_with_disabled_returns_no_checks():
  29. checks = module.parse_checks({'checks': [{'name': 'foo'}, {'name': 'disabled'}]})
  30. assert checks == ()
  31. def test_parse_checks_prefers_override_checks_to_configured_checks():
  32. checks = module.parse_checks(
  33. {'checks': [{'name': 'archives'}]}, only_checks=['repository', 'extract']
  34. )
  35. assert checks == ('repository', 'extract')
  36. @pytest.mark.parametrize(
  37. 'frequency,expected_result',
  38. (
  39. (None, None),
  40. ('always', None),
  41. ('1 hour', module.datetime.timedelta(hours=1)),
  42. ('2 hours', module.datetime.timedelta(hours=2)),
  43. ('1 day', module.datetime.timedelta(days=1)),
  44. ('2 days', module.datetime.timedelta(days=2)),
  45. ('1 week', module.datetime.timedelta(weeks=1)),
  46. ('2 weeks', module.datetime.timedelta(weeks=2)),
  47. ('1 month', module.datetime.timedelta(days=30)),
  48. ('2 months', module.datetime.timedelta(days=60)),
  49. ('1 year', module.datetime.timedelta(days=365)),
  50. ('2 years', module.datetime.timedelta(days=365 * 2)),
  51. ),
  52. )
  53. def test_parse_frequency_parses_into_timedeltas(frequency, expected_result):
  54. assert module.parse_frequency(frequency) == expected_result
  55. @pytest.mark.parametrize(
  56. 'frequency',
  57. (
  58. 'sometime',
  59. 'x days',
  60. '3 decades',
  61. ),
  62. )
  63. def test_parse_frequency_raises_on_parse_error(frequency):
  64. with pytest.raises(ValueError):
  65. module.parse_frequency(frequency)
  66. def test_filter_checks_on_frequency_without_config_uses_default_checks():
  67. flexmock(module).should_receive('parse_frequency').and_return(
  68. module.datetime.timedelta(weeks=4)
  69. )
  70. flexmock(module).should_receive('make_check_time_path')
  71. flexmock(module).should_receive('probe_for_check_time').and_return(None)
  72. assert module.filter_checks_on_frequency(
  73. config={},
  74. borg_repository_id='repo',
  75. checks=('repository', 'archives'),
  76. force=False,
  77. archives_check_id='1234',
  78. ) == ('repository', 'archives')
  79. def test_filter_checks_on_frequency_retains_unconfigured_check():
  80. assert module.filter_checks_on_frequency(
  81. config={},
  82. borg_repository_id='repo',
  83. checks=('data',),
  84. force=False,
  85. ) == ('data',)
  86. def test_filter_checks_on_frequency_retains_check_without_frequency():
  87. flexmock(module).should_receive('parse_frequency').and_return(None)
  88. assert module.filter_checks_on_frequency(
  89. config={'checks': [{'name': 'archives'}]},
  90. borg_repository_id='repo',
  91. checks=('archives',),
  92. force=False,
  93. archives_check_id='1234',
  94. ) == ('archives',)
  95. def test_filter_checks_on_frequency_retains_check_with_elapsed_frequency():
  96. flexmock(module).should_receive('parse_frequency').and_return(
  97. module.datetime.timedelta(hours=1)
  98. )
  99. flexmock(module).should_receive('make_check_time_path')
  100. flexmock(module).should_receive('probe_for_check_time').and_return(
  101. module.datetime.datetime(year=module.datetime.MINYEAR, month=1, day=1)
  102. )
  103. assert module.filter_checks_on_frequency(
  104. config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  105. borg_repository_id='repo',
  106. checks=('archives',),
  107. force=False,
  108. archives_check_id='1234',
  109. ) == ('archives',)
  110. def test_filter_checks_on_frequency_retains_check_with_missing_check_time_file():
  111. flexmock(module).should_receive('parse_frequency').and_return(
  112. module.datetime.timedelta(hours=1)
  113. )
  114. flexmock(module).should_receive('make_check_time_path')
  115. flexmock(module).should_receive('probe_for_check_time').and_return(None)
  116. assert module.filter_checks_on_frequency(
  117. config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  118. borg_repository_id='repo',
  119. checks=('archives',),
  120. force=False,
  121. archives_check_id='1234',
  122. ) == ('archives',)
  123. def test_filter_checks_on_frequency_skips_check_with_unelapsed_frequency():
  124. flexmock(module).should_receive('parse_frequency').and_return(
  125. module.datetime.timedelta(hours=1)
  126. )
  127. flexmock(module).should_receive('make_check_time_path')
  128. flexmock(module).should_receive('probe_for_check_time').and_return(
  129. module.datetime.datetime.now()
  130. )
  131. assert (
  132. module.filter_checks_on_frequency(
  133. config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  134. borg_repository_id='repo',
  135. checks=('archives',),
  136. force=False,
  137. archives_check_id='1234',
  138. )
  139. == ()
  140. )
  141. def test_filter_checks_on_frequency_restains_check_with_unelapsed_frequency_and_force():
  142. assert module.filter_checks_on_frequency(
  143. config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  144. borg_repository_id='repo',
  145. checks=('archives',),
  146. force=True,
  147. archives_check_id='1234',
  148. ) == ('archives',)
  149. def test_filter_checks_on_frequency_passes_through_empty_checks():
  150. assert (
  151. module.filter_checks_on_frequency(
  152. config={'checks': [{'name': 'archives', 'frequency': '1 hour'}]},
  153. borg_repository_id='repo',
  154. checks=(),
  155. force=False,
  156. archives_check_id='1234',
  157. )
  158. == ()
  159. )
  160. def test_make_archive_filter_flags_with_default_checks_and_prefix_returns_default_flags():
  161. flexmock(module.feature).should_receive('available').and_return(True)
  162. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  163. flags = module.make_archive_filter_flags(
  164. '1.2.3',
  165. {},
  166. ('repository', 'archives'),
  167. check_arguments=flexmock(match_archives=None),
  168. prefix='foo',
  169. )
  170. assert flags == ('--match-archives', 'sh:foo*')
  171. def test_make_archive_filter_flags_with_all_checks_and_prefix_returns_default_flags():
  172. flexmock(module.feature).should_receive('available').and_return(True)
  173. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  174. flags = module.make_archive_filter_flags(
  175. '1.2.3',
  176. {},
  177. ('repository', 'archives', 'extract'),
  178. check_arguments=flexmock(match_archives=None),
  179. prefix='foo',
  180. )
  181. assert flags == ('--match-archives', 'sh:foo*')
  182. def test_make_archive_filter_flags_with_all_checks_and_prefix_without_borg_features_returns_glob_archives_flags():
  183. flexmock(module.feature).should_receive('available').and_return(False)
  184. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  185. flags = module.make_archive_filter_flags(
  186. '1.2.3',
  187. {},
  188. ('repository', 'archives', 'extract'),
  189. check_arguments=flexmock(match_archives=None),
  190. prefix='foo',
  191. )
  192. assert flags == ('--glob-archives', 'foo*')
  193. def test_make_archive_filter_flags_with_archives_check_and_last_includes_last_flag():
  194. flexmock(module.feature).should_receive('available').and_return(True)
  195. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  196. flags = module.make_archive_filter_flags(
  197. '1.2.3', {}, ('archives',), check_arguments=flexmock(match_archives=None), check_last=3
  198. )
  199. assert flags == ('--last', '3')
  200. def test_make_archive_filter_flags_with_data_check_and_last_includes_last_flag():
  201. flexmock(module.feature).should_receive('available').and_return(True)
  202. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  203. flags = module.make_archive_filter_flags(
  204. '1.2.3', {}, ('data',), check_arguments=flexmock(match_archives=None), check_last=3
  205. )
  206. assert flags == ('--last', '3')
  207. def test_make_archive_filter_flags_with_repository_check_and_last_omits_last_flag():
  208. flexmock(module.feature).should_receive('available').and_return(True)
  209. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  210. flags = module.make_archive_filter_flags(
  211. '1.2.3', {}, ('repository',), check_arguments=flexmock(match_archives=None), check_last=3
  212. )
  213. assert flags == ()
  214. def test_make_archive_filter_flags_with_default_checks_and_last_includes_last_flag():
  215. flexmock(module.feature).should_receive('available').and_return(True)
  216. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  217. flags = module.make_archive_filter_flags(
  218. '1.2.3',
  219. {},
  220. ('repository', 'archives'),
  221. check_arguments=flexmock(match_archives=None),
  222. check_last=3,
  223. )
  224. assert flags == ('--last', '3')
  225. def test_make_archive_filter_flags_with_archives_check_and_prefix_includes_match_archives_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_archive_filter_flags(
  229. '1.2.3', {}, ('archives',), check_arguments=flexmock(match_archives=None), prefix='foo-'
  230. )
  231. assert flags == ('--match-archives', 'sh:foo-*')
  232. def test_make_archive_filter_flags_with_data_check_and_prefix_includes_match_archives_flag():
  233. flexmock(module.feature).should_receive('available').and_return(True)
  234. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  235. flags = module.make_archive_filter_flags(
  236. '1.2.3', {}, ('data',), check_arguments=flexmock(match_archives=None), prefix='foo-'
  237. )
  238. assert flags == ('--match-archives', 'sh:foo-*')
  239. def test_make_archive_filter_flags_prefers_check_arguments_match_archives_to_config_match_archives():
  240. flexmock(module.feature).should_receive('available').and_return(True)
  241. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  242. 'baz-*', None, '1.2.3'
  243. ).and_return(('--match-archives', 'sh:baz-*'))
  244. flags = module.make_archive_filter_flags(
  245. '1.2.3',
  246. {'match_archives': 'bar-{now}'}, # noqa: FS003
  247. ('archives',),
  248. check_arguments=flexmock(match_archives='baz-*'),
  249. prefix='',
  250. )
  251. assert flags == ('--match-archives', 'sh:baz-*')
  252. def test_make_archive_filter_flags_with_archives_check_and_empty_prefix_uses_archive_name_format_instead():
  253. flexmock(module.feature).should_receive('available').and_return(True)
  254. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  255. None, 'bar-{now}', '1.2.3' # noqa: FS003
  256. ).and_return(('--match-archives', 'sh:bar-*'))
  257. flags = module.make_archive_filter_flags(
  258. '1.2.3',
  259. {'archive_name_format': 'bar-{now}'}, # noqa: FS003
  260. ('archives',),
  261. check_arguments=flexmock(match_archives=None),
  262. prefix='',
  263. )
  264. assert flags == ('--match-archives', 'sh:bar-*')
  265. def test_make_archive_filter_flags_with_archives_check_and_none_prefix_omits_match_archives_flag():
  266. flexmock(module.feature).should_receive('available').and_return(True)
  267. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  268. flags = module.make_archive_filter_flags(
  269. '1.2.3', {}, ('archives',), check_arguments=flexmock(match_archives=None), prefix=None
  270. )
  271. assert flags == ()
  272. def test_make_archive_filter_flags_with_repository_check_and_prefix_omits_match_archives_flag():
  273. flexmock(module.feature).should_receive('available').and_return(True)
  274. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  275. flags = module.make_archive_filter_flags(
  276. '1.2.3', {}, ('repository',), check_arguments=flexmock(match_archives=None), prefix='foo-'
  277. )
  278. assert flags == ()
  279. def test_make_archive_filter_flags_with_default_checks_and_prefix_includes_match_archives_flag():
  280. flexmock(module.feature).should_receive('available').and_return(True)
  281. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  282. flags = module.make_archive_filter_flags(
  283. '1.2.3',
  284. {},
  285. ('repository', 'archives'),
  286. check_arguments=flexmock(match_archives=None),
  287. prefix='foo-',
  288. )
  289. assert flags == ('--match-archives', 'sh:foo-*')
  290. def test_make_archives_check_id_with_flags_returns_a_value_and_does_not_raise():
  291. assert module.make_archives_check_id(('--match-archives', 'sh:foo-*'))
  292. def test_make_archives_check_id_with_empty_flags_returns_none():
  293. assert module.make_archives_check_id(()) is None
  294. def test_make_check_flags_with_repository_check_returns_flag():
  295. flags = module.make_check_flags(('repository',), ())
  296. assert flags == ('--repository-only',)
  297. def test_make_check_flags_with_archives_check_returns_flag():
  298. flags = module.make_check_flags(('archives',), ())
  299. assert flags == ('--archives-only',)
  300. def test_make_check_flags_with_archives_check_and_archive_filter_flags_includes_those_flags():
  301. flags = module.make_check_flags(('archives',), ('--match-archives', 'sh:foo-*'))
  302. assert flags == ('--archives-only', '--match-archives', 'sh:foo-*')
  303. def test_make_check_flags_without_archives_check_and_with_archive_filter_flags_includes_those_flags():
  304. flags = module.make_check_flags(('repository',), ('--match-archives', 'sh:foo-*'))
  305. assert flags == ('--repository-only',)
  306. def test_make_check_flags_with_data_check_returns_flag_and_implies_archives():
  307. flexmock(module.feature).should_receive('available').and_return(True)
  308. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  309. flags = module.make_check_flags(('data',), ())
  310. assert flags == (
  311. '--archives-only',
  312. '--verify-data',
  313. )
  314. def test_make_check_flags_with_extract_omits_extract_flag():
  315. flexmock(module.feature).should_receive('available').and_return(True)
  316. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  317. flags = module.make_check_flags(('extract',), ())
  318. assert flags == ()
  319. def test_make_check_flags_with_repository_and_data_checks_does_not_return_repository_only():
  320. flexmock(module.feature).should_receive('available').and_return(True)
  321. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  322. flags = module.make_check_flags(
  323. (
  324. 'repository',
  325. 'data',
  326. ),
  327. (),
  328. )
  329. assert flags == ('--verify-data',)
  330. def test_make_check_time_path_with_borgmatic_source_directory_includes_it():
  331. flexmock(module.os.path).should_receive('expanduser').with_args('~/.borgmatic').and_return(
  332. '/home/user/.borgmatic'
  333. )
  334. assert (
  335. module.make_check_time_path(
  336. {'borgmatic_source_directory': '~/.borgmatic'}, '1234', 'archives', '5678'
  337. )
  338. == '/home/user/.borgmatic/checks/1234/archives/5678'
  339. )
  340. def test_make_check_time_path_without_borgmatic_source_directory_uses_default():
  341. flexmock(module.os.path).should_receive('expanduser').with_args(
  342. module.state.DEFAULT_BORGMATIC_SOURCE_DIRECTORY
  343. ).and_return('/home/user/.borgmatic')
  344. assert (
  345. module.make_check_time_path({}, '1234', 'archives', '5678')
  346. == '/home/user/.borgmatic/checks/1234/archives/5678'
  347. )
  348. def test_make_check_time_path_with_archives_check_and_no_archives_check_id_defaults_to_all():
  349. flexmock(module.os.path).should_receive('expanduser').with_args('~/.borgmatic').and_return(
  350. '/home/user/.borgmatic'
  351. )
  352. assert (
  353. module.make_check_time_path(
  354. {'borgmatic_source_directory': '~/.borgmatic'},
  355. '1234',
  356. 'archives',
  357. )
  358. == '/home/user/.borgmatic/checks/1234/archives/all'
  359. )
  360. def test_make_check_time_path_with_repositories_check_ignores_archives_check_id():
  361. flexmock(module.os.path).should_receive('expanduser').with_args('~/.borgmatic').and_return(
  362. '/home/user/.borgmatic'
  363. )
  364. assert (
  365. module.make_check_time_path(
  366. {'borgmatic_source_directory': '~/.borgmatic'}, '1234', 'repository', '5678'
  367. )
  368. == '/home/user/.borgmatic/checks/1234/repository'
  369. )
  370. def test_read_check_time_does_not_raise():
  371. flexmock(module.os).should_receive('stat').and_return(flexmock(st_mtime=123))
  372. assert module.read_check_time('/path')
  373. def test_read_check_time_on_missing_file_does_not_raise():
  374. flexmock(module.os).should_receive('stat').and_raise(FileNotFoundError)
  375. assert module.read_check_time('/path') is None
  376. def test_probe_for_check_time_uses_maximum_of_multiple_check_times():
  377. flexmock(module).should_receive('make_check_time_path').and_return(
  378. '~/.borgmatic/checks/1234/archives/5678'
  379. ).and_return('~/.borgmatic/checks/1234/archives/all')
  380. flexmock(module).should_receive('read_check_time').and_return(1).and_return(2)
  381. assert module.probe_for_check_time(flexmock(), flexmock(), flexmock(), flexmock()) == 2
  382. def test_probe_for_check_time_deduplicates_identical_check_time_paths():
  383. flexmock(module).should_receive('make_check_time_path').and_return(
  384. '~/.borgmatic/checks/1234/archives/5678'
  385. ).and_return('~/.borgmatic/checks/1234/archives/5678')
  386. flexmock(module).should_receive('read_check_time').and_return(1).once()
  387. assert module.probe_for_check_time(flexmock(), flexmock(), flexmock(), flexmock()) == 1
  388. def test_probe_for_check_time_skips_none_check_time():
  389. flexmock(module).should_receive('make_check_time_path').and_return(
  390. '~/.borgmatic/checks/1234/archives/5678'
  391. ).and_return('~/.borgmatic/checks/1234/archives/all')
  392. flexmock(module).should_receive('read_check_time').and_return(None).and_return(2)
  393. assert module.probe_for_check_time(flexmock(), flexmock(), flexmock(), flexmock()) == 2
  394. def test_probe_for_check_time_uses_single_check_time():
  395. flexmock(module).should_receive('make_check_time_path').and_return(
  396. '~/.borgmatic/checks/1234/archives/5678'
  397. ).and_return('~/.borgmatic/checks/1234/archives/all')
  398. flexmock(module).should_receive('read_check_time').and_return(1).and_return(None)
  399. assert module.probe_for_check_time(flexmock(), flexmock(), flexmock(), flexmock()) == 1
  400. def test_probe_for_check_time_returns_none_when_no_check_time_found():
  401. flexmock(module).should_receive('make_check_time_path').and_return(
  402. '~/.borgmatic/checks/1234/archives/5678'
  403. ).and_return('~/.borgmatic/checks/1234/archives/all')
  404. flexmock(module).should_receive('read_check_time').and_return(None).and_return(None)
  405. assert module.probe_for_check_time(flexmock(), flexmock(), flexmock(), flexmock()) is None
  406. def test_upgrade_check_times_renames_old_check_paths_to_all():
  407. base_path = '~/.borgmatic/checks/1234'
  408. flexmock(module).should_receive('make_check_time_path').with_args(
  409. object, object, 'archives', 'all'
  410. ).and_return(f'{base_path}/archives/all')
  411. flexmock(module).should_receive('make_check_time_path').with_args(
  412. object, object, 'data', 'all'
  413. ).and_return(f'{base_path}/data/all')
  414. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return(
  415. True
  416. )
  417. flexmock(module.os.path).should_receive('isfile').with_args(
  418. f'{base_path}/archives.temp'
  419. ).and_return(False)
  420. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return(
  421. False
  422. )
  423. flexmock(module.os.path).should_receive('isfile').with_args(
  424. f'{base_path}/data.temp'
  425. ).and_return(False)
  426. flexmock(module.os).should_receive('rename').with_args(
  427. f'{base_path}/archives', f'{base_path}/archives.temp'
  428. ).once()
  429. flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/archives').once()
  430. flexmock(module.os).should_receive('rename').with_args(
  431. f'{base_path}/archives.temp', f'{base_path}/archives/all'
  432. ).once()
  433. module.upgrade_check_times(flexmock(), flexmock())
  434. def test_upgrade_check_times_renames_data_check_paths_when_archives_paths_are_already_upgraded():
  435. base_path = '~/.borgmatic/checks/1234'
  436. flexmock(module).should_receive('make_check_time_path').with_args(
  437. object, object, 'archives', 'all'
  438. ).and_return(f'{base_path}/archives/all')
  439. flexmock(module).should_receive('make_check_time_path').with_args(
  440. object, object, 'data', 'all'
  441. ).and_return(f'{base_path}/data/all')
  442. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return(
  443. False
  444. )
  445. flexmock(module.os.path).should_receive('isfile').with_args(
  446. f'{base_path}/archives.temp'
  447. ).and_return(False)
  448. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return(
  449. True
  450. )
  451. flexmock(module.os).should_receive('rename').with_args(
  452. f'{base_path}/data', f'{base_path}/data.temp'
  453. ).once()
  454. flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/data').once()
  455. flexmock(module.os).should_receive('rename').with_args(
  456. f'{base_path}/data.temp', f'{base_path}/data/all'
  457. ).once()
  458. module.upgrade_check_times(flexmock(), flexmock())
  459. def test_upgrade_check_times_skips_missing_check_paths():
  460. flexmock(module).should_receive('make_check_time_path').and_return(
  461. '~/.borgmatic/checks/1234/archives/all'
  462. )
  463. flexmock(module.os.path).should_receive('isfile').and_return(False)
  464. flexmock(module.os).should_receive('rename').never()
  465. flexmock(module.os).should_receive('mkdir').never()
  466. module.upgrade_check_times(flexmock(), flexmock())
  467. def test_upgrade_check_times_renames_stale_temporary_check_path():
  468. base_path = '~/.borgmatic/checks/1234'
  469. flexmock(module).should_receive('make_check_time_path').with_args(
  470. object, object, 'archives', 'all'
  471. ).and_return(f'{base_path}/archives/all')
  472. flexmock(module).should_receive('make_check_time_path').with_args(
  473. object, object, 'data', 'all'
  474. ).and_return(f'{base_path}/data/all')
  475. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/archives').and_return(
  476. False
  477. )
  478. flexmock(module.os.path).should_receive('isfile').with_args(
  479. f'{base_path}/archives.temp'
  480. ).and_return(True)
  481. flexmock(module.os.path).should_receive('isfile').with_args(f'{base_path}/data').and_return(
  482. False
  483. )
  484. flexmock(module.os.path).should_receive('isfile').with_args(
  485. f'{base_path}/data.temp'
  486. ).and_return(False)
  487. flexmock(module.os).should_receive('rename').with_args(
  488. f'{base_path}/archives', f'{base_path}/archives.temp'
  489. ).and_raise(FileNotFoundError)
  490. flexmock(module.os).should_receive('mkdir').with_args(f'{base_path}/archives').once()
  491. flexmock(module.os).should_receive('rename').with_args(
  492. f'{base_path}/archives.temp', f'{base_path}/archives/all'
  493. ).once()
  494. module.upgrade_check_times(flexmock(), flexmock())
  495. def test_check_archives_with_progress_passes_through_to_borg():
  496. checks = ('repository',)
  497. config = {'check_last': None}
  498. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  499. '{"repository": {"id": "repo"}}'
  500. )
  501. flexmock(module).should_receive('upgrade_check_times')
  502. flexmock(module).should_receive('parse_checks')
  503. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  504. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  505. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  506. flexmock(module).should_receive('make_check_flags').and_return(())
  507. flexmock(module).should_receive('execute_command').never()
  508. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  509. flexmock(module.environment).should_receive('make_environment')
  510. flexmock(module).should_receive('execute_command').with_args(
  511. ('borg', 'check', '--progress', 'repo'),
  512. output_file=module.DO_NOT_CAPTURE,
  513. extra_environment=None,
  514. borg_local_path='borg',
  515. borg_exit_codes=None,
  516. ).once()
  517. flexmock(module).should_receive('make_check_time_path')
  518. flexmock(module).should_receive('write_check_time')
  519. module.check_archives(
  520. repository_path='repo',
  521. config=config,
  522. local_borg_version='1.2.3',
  523. check_arguments=flexmock(
  524. progress=True, repair=None, only_checks=None, force=None, match_archives=None
  525. ),
  526. global_arguments=flexmock(log_json=False),
  527. )
  528. def test_check_archives_with_repair_passes_through_to_borg():
  529. checks = ('repository',)
  530. config = {'check_last': None}
  531. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  532. '{"repository": {"id": "repo"}}'
  533. )
  534. flexmock(module).should_receive('upgrade_check_times')
  535. flexmock(module).should_receive('parse_checks')
  536. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  537. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  538. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  539. flexmock(module).should_receive('make_check_flags').and_return(())
  540. flexmock(module).should_receive('execute_command').never()
  541. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  542. flexmock(module.environment).should_receive('make_environment')
  543. flexmock(module).should_receive('execute_command').with_args(
  544. ('borg', 'check', '--repair', 'repo'),
  545. output_file=module.DO_NOT_CAPTURE,
  546. extra_environment=None,
  547. borg_local_path='borg',
  548. borg_exit_codes=None,
  549. ).once()
  550. flexmock(module).should_receive('make_check_time_path')
  551. flexmock(module).should_receive('write_check_time')
  552. module.check_archives(
  553. repository_path='repo',
  554. config=config,
  555. local_borg_version='1.2.3',
  556. check_arguments=flexmock(
  557. progress=None, repair=True, only_checks=None, force=None, match_archives=None
  558. ),
  559. global_arguments=flexmock(log_json=False),
  560. )
  561. @pytest.mark.parametrize(
  562. 'checks',
  563. (
  564. ('repository',),
  565. ('archives',),
  566. ('repository', 'archives'),
  567. ('repository', 'archives', 'other'),
  568. ),
  569. )
  570. def test_check_archives_calls_borg_with_parameters(checks):
  571. check_last = flexmock()
  572. config = {'check_last': check_last}
  573. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  574. '{"repository": {"id": "repo"}}'
  575. )
  576. flexmock(module).should_receive('upgrade_check_times')
  577. flexmock(module).should_receive('parse_checks')
  578. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  579. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  580. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  581. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  582. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  583. insert_execute_command_mock(('borg', 'check', '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. config=config,
  589. local_borg_version='1.2.3',
  590. check_arguments=flexmock(
  591. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  592. ),
  593. global_arguments=flexmock(log_json=False),
  594. )
  595. def test_check_archives_with_json_error_raises():
  596. checks = ('archives',)
  597. check_last = flexmock()
  598. config = {'check_last': check_last}
  599. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  600. '{"unexpected": {"id": "repo"}}'
  601. )
  602. flexmock(module).should_receive('upgrade_check_times')
  603. flexmock(module).should_receive('parse_checks')
  604. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  605. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  606. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  607. with pytest.raises(ValueError):
  608. module.check_archives(
  609. repository_path='repo',
  610. config=config,
  611. local_borg_version='1.2.3',
  612. check_arguments=flexmock(
  613. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  614. ),
  615. global_arguments=flexmock(log_json=False),
  616. )
  617. def test_check_archives_with_missing_json_keys_raises():
  618. checks = ('archives',)
  619. check_last = flexmock()
  620. config = {'check_last': check_last}
  621. flexmock(module.rinfo).should_receive('display_repository_info').and_return('{invalid JSON')
  622. flexmock(module).should_receive('upgrade_check_times')
  623. flexmock(module).should_receive('parse_checks')
  624. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  625. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  626. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  627. with pytest.raises(ValueError):
  628. module.check_archives(
  629. repository_path='repo',
  630. config=config,
  631. local_borg_version='1.2.3',
  632. check_arguments=flexmock(
  633. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  634. ),
  635. global_arguments=flexmock(log_json=False),
  636. )
  637. def test_check_archives_with_extract_check_calls_extract_only():
  638. checks = ('extract',)
  639. check_last = flexmock()
  640. config = {'check_last': check_last}
  641. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  642. '{"repository": {"id": "repo"}}'
  643. )
  644. flexmock(module).should_receive('upgrade_check_times')
  645. flexmock(module).should_receive('parse_checks')
  646. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  647. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  648. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  649. flexmock(module).should_receive('make_check_flags').never()
  650. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  651. flexmock(module.extract).should_receive('extract_last_archive_dry_run').once()
  652. flexmock(module).should_receive('write_check_time')
  653. insert_execute_command_never()
  654. module.check_archives(
  655. repository_path='repo',
  656. config=config,
  657. local_borg_version='1.2.3',
  658. check_arguments=flexmock(
  659. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  660. ),
  661. global_arguments=flexmock(log_json=False),
  662. )
  663. def test_check_archives_with_log_info_passes_through_to_borg():
  664. checks = ('repository',)
  665. config = {'check_last': None}
  666. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  667. '{"repository": {"id": "repo"}}'
  668. )
  669. flexmock(module).should_receive('upgrade_check_times')
  670. flexmock(module).should_receive('parse_checks')
  671. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  672. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  673. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  674. flexmock(module).should_receive('make_check_flags').and_return(())
  675. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  676. insert_logging_mock(logging.INFO)
  677. insert_execute_command_mock(('borg', 'check', '--info', 'repo'))
  678. flexmock(module).should_receive('make_check_time_path')
  679. flexmock(module).should_receive('write_check_time')
  680. module.check_archives(
  681. repository_path='repo',
  682. config=config,
  683. local_borg_version='1.2.3',
  684. check_arguments=flexmock(
  685. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  686. ),
  687. global_arguments=flexmock(log_json=False),
  688. )
  689. def test_check_archives_with_log_debug_passes_through_to_borg():
  690. checks = ('repository',)
  691. config = {'check_last': None}
  692. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  693. '{"repository": {"id": "repo"}}'
  694. )
  695. flexmock(module).should_receive('upgrade_check_times')
  696. flexmock(module).should_receive('parse_checks')
  697. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  698. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  699. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  700. flexmock(module).should_receive('make_check_flags').and_return(())
  701. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  702. insert_logging_mock(logging.DEBUG)
  703. insert_execute_command_mock(('borg', 'check', '--debug', '--show-rc', 'repo'))
  704. flexmock(module).should_receive('make_check_time_path')
  705. flexmock(module).should_receive('write_check_time')
  706. module.check_archives(
  707. repository_path='repo',
  708. config=config,
  709. local_borg_version='1.2.3',
  710. check_arguments=flexmock(
  711. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  712. ),
  713. global_arguments=flexmock(log_json=False),
  714. )
  715. def test_check_archives_without_any_checks_bails():
  716. config = {'check_last': None}
  717. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  718. '{"repository": {"id": "repo"}}'
  719. )
  720. flexmock(module).should_receive('upgrade_check_times')
  721. flexmock(module).should_receive('parse_checks')
  722. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  723. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  724. flexmock(module).should_receive('filter_checks_on_frequency').and_return(())
  725. insert_execute_command_never()
  726. module.check_archives(
  727. repository_path='repo',
  728. config=config,
  729. local_borg_version='1.2.3',
  730. check_arguments=flexmock(
  731. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  732. ),
  733. global_arguments=flexmock(log_json=False),
  734. )
  735. def test_check_archives_with_local_path_calls_borg_via_local_path():
  736. checks = ('repository',)
  737. check_last = flexmock()
  738. config = {'check_last': check_last}
  739. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  740. '{"repository": {"id": "repo"}}'
  741. )
  742. flexmock(module).should_receive('upgrade_check_times')
  743. flexmock(module).should_receive('parse_checks')
  744. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  745. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  746. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  747. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  748. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  749. insert_execute_command_mock(('borg1', 'check', 'repo'))
  750. flexmock(module).should_receive('make_check_time_path')
  751. flexmock(module).should_receive('write_check_time')
  752. module.check_archives(
  753. repository_path='repo',
  754. config=config,
  755. local_borg_version='1.2.3',
  756. check_arguments=flexmock(
  757. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  758. ),
  759. global_arguments=flexmock(log_json=False),
  760. local_path='borg1',
  761. )
  762. def test_check_archives_with_exit_codes_calls_borg_using_them():
  763. checks = ('repository',)
  764. check_last = flexmock()
  765. borg_exit_codes = flexmock()
  766. config = {'check_last': check_last, 'borg_exit_codes': borg_exit_codes}
  767. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  768. '{"repository": {"id": "repo"}}'
  769. )
  770. flexmock(module).should_receive('upgrade_check_times')
  771. flexmock(module).should_receive('parse_checks')
  772. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  773. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  774. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  775. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  776. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  777. insert_execute_command_mock(('borg', 'check', 'repo'), borg_exit_codes=borg_exit_codes)
  778. flexmock(module).should_receive('make_check_time_path')
  779. flexmock(module).should_receive('write_check_time')
  780. module.check_archives(
  781. repository_path='repo',
  782. config=config,
  783. local_borg_version='1.2.3',
  784. check_arguments=flexmock(
  785. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  786. ),
  787. global_arguments=flexmock(log_json=False),
  788. )
  789. def test_check_archives_with_remote_path_passes_through_to_borg():
  790. checks = ('repository',)
  791. check_last = flexmock()
  792. config = {'check_last': check_last}
  793. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  794. '{"repository": {"id": "repo"}}'
  795. )
  796. flexmock(module).should_receive('upgrade_check_times')
  797. flexmock(module).should_receive('parse_checks')
  798. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  799. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  800. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  801. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  802. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  803. insert_execute_command_mock(('borg', 'check', '--remote-path', 'borg1', 'repo'))
  804. flexmock(module).should_receive('make_check_time_path')
  805. flexmock(module).should_receive('write_check_time')
  806. module.check_archives(
  807. repository_path='repo',
  808. config=config,
  809. local_borg_version='1.2.3',
  810. check_arguments=flexmock(
  811. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  812. ),
  813. global_arguments=flexmock(log_json=False),
  814. remote_path='borg1',
  815. )
  816. def test_check_archives_with_log_json_passes_through_to_borg():
  817. checks = ('repository',)
  818. check_last = flexmock()
  819. config = {'check_last': check_last}
  820. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  821. '{"repository": {"id": "repo"}}'
  822. )
  823. flexmock(module).should_receive('upgrade_check_times')
  824. flexmock(module).should_receive('parse_checks')
  825. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  826. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  827. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  828. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  829. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  830. insert_execute_command_mock(('borg', 'check', '--log-json', 'repo'))
  831. flexmock(module).should_receive('make_check_time_path')
  832. flexmock(module).should_receive('write_check_time')
  833. module.check_archives(
  834. repository_path='repo',
  835. config=config,
  836. local_borg_version='1.2.3',
  837. check_arguments=flexmock(
  838. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  839. ),
  840. global_arguments=flexmock(log_json=True),
  841. )
  842. def test_check_archives_with_lock_wait_passes_through_to_borg():
  843. checks = ('repository',)
  844. check_last = flexmock()
  845. config = {'lock_wait': 5, 'check_last': check_last}
  846. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  847. '{"repository": {"id": "repo"}}'
  848. )
  849. flexmock(module).should_receive('upgrade_check_times')
  850. flexmock(module).should_receive('parse_checks')
  851. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  852. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  853. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  854. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  855. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  856. insert_execute_command_mock(('borg', 'check', '--lock-wait', '5', 'repo'))
  857. flexmock(module).should_receive('make_check_time_path')
  858. flexmock(module).should_receive('write_check_time')
  859. module.check_archives(
  860. repository_path='repo',
  861. config=config,
  862. local_borg_version='1.2.3',
  863. check_arguments=flexmock(
  864. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  865. ),
  866. global_arguments=flexmock(log_json=False),
  867. )
  868. def test_check_archives_with_retention_prefix():
  869. checks = ('repository',)
  870. check_last = flexmock()
  871. prefix = 'foo-'
  872. config = {'check_last': check_last, 'prefix': prefix}
  873. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  874. '{"repository": {"id": "repo"}}'
  875. )
  876. flexmock(module).should_receive('upgrade_check_times')
  877. flexmock(module).should_receive('parse_checks')
  878. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  879. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  880. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  881. flexmock(module).should_receive('make_check_flags').with_args(checks, ()).and_return(())
  882. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  883. insert_execute_command_mock(('borg', 'check', 'repo'))
  884. flexmock(module).should_receive('make_check_time_path')
  885. flexmock(module).should_receive('write_check_time')
  886. module.check_archives(
  887. repository_path='repo',
  888. config=config,
  889. local_borg_version='1.2.3',
  890. check_arguments=flexmock(
  891. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  892. ),
  893. global_arguments=flexmock(log_json=False),
  894. )
  895. def test_check_archives_with_extra_borg_options_passes_through_to_borg():
  896. checks = ('repository',)
  897. config = {'check_last': None, 'extra_borg_options': {'check': '--extra --options'}}
  898. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  899. '{"repository": {"id": "repo"}}'
  900. )
  901. flexmock(module).should_receive('upgrade_check_times')
  902. flexmock(module).should_receive('parse_checks')
  903. flexmock(module).should_receive('make_archive_filter_flags').and_return(())
  904. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  905. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  906. flexmock(module).should_receive('make_check_flags').and_return(())
  907. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  908. insert_execute_command_mock(('borg', 'check', '--extra', '--options', 'repo'))
  909. flexmock(module).should_receive('make_check_time_path')
  910. flexmock(module).should_receive('write_check_time')
  911. module.check_archives(
  912. repository_path='repo',
  913. config=config,
  914. local_borg_version='1.2.3',
  915. check_arguments=flexmock(
  916. progress=None, repair=None, only_checks=None, force=None, match_archives=None
  917. ),
  918. global_arguments=flexmock(log_json=False),
  919. )
  920. def test_check_archives_with_match_archives_passes_through_to_borg():
  921. checks = ('archives',)
  922. config = {'check_last': None}
  923. flexmock(module.rinfo).should_receive('display_repository_info').and_return(
  924. '{"repository": {"id": "repo"}}'
  925. )
  926. flexmock(module).should_receive('upgrade_check_times')
  927. flexmock(module).should_receive('parse_checks')
  928. flexmock(module).should_receive('make_archive_filter_flags').and_return(
  929. ('--match-archives', 'foo-*')
  930. )
  931. flexmock(module).should_receive('make_archives_check_id').and_return(None)
  932. flexmock(module).should_receive('filter_checks_on_frequency').and_return(checks)
  933. flexmock(module).should_receive('make_check_flags').and_return(('--match-archives', 'foo-*'))
  934. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  935. flexmock(module.environment).should_receive('make_environment')
  936. flexmock(module).should_receive('execute_command').with_args(
  937. ('borg', 'check', '--match-archives', 'foo-*', 'repo'),
  938. extra_environment=None,
  939. borg_local_path='borg',
  940. borg_exit_codes=None,
  941. ).once()
  942. flexmock(module).should_receive('make_check_time_path')
  943. flexmock(module).should_receive('write_check_time')
  944. module.check_archives(
  945. repository_path='repo',
  946. config=config,
  947. local_borg_version='1.2.3',
  948. check_arguments=flexmock(
  949. progress=None, repair=None, only_checks=None, force=None, match_archives='foo-*'
  950. ),
  951. global_arguments=flexmock(log_json=False),
  952. )