test_list.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. import argparse
  2. import logging
  3. import pytest
  4. from flexmock import flexmock
  5. from borgmatic.borg import list as module
  6. from ..test_verbosity import insert_logging_mock
  7. def test_make_list_command_includes_log_info():
  8. insert_logging_mock(logging.INFO)
  9. flexmock(module.flags).should_receive('make_flags').and_return(())
  10. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  11. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  12. command = module.make_list_command(
  13. repository_path='repo',
  14. config={},
  15. local_borg_version='1.2.3',
  16. list_arguments=flexmock(archive=None, paths=None, json=False),
  17. global_arguments=flexmock(),
  18. )
  19. assert command == ('borg', 'list', '--info', 'repo')
  20. def test_make_list_command_includes_json_but_not_info():
  21. insert_logging_mock(logging.INFO)
  22. flexmock(module.flags).should_receive('make_flags').and_return(())
  23. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
  24. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  25. command = module.make_list_command(
  26. repository_path='repo',
  27. config={},
  28. local_borg_version='1.2.3',
  29. list_arguments=flexmock(archive=None, paths=None, json=True),
  30. global_arguments=flexmock(),
  31. )
  32. assert command == ('borg', 'list', '--json', 'repo')
  33. def test_make_list_command_includes_log_debug():
  34. insert_logging_mock(logging.DEBUG)
  35. flexmock(module.flags).should_receive('make_flags').and_return(())
  36. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  37. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  38. command = module.make_list_command(
  39. repository_path='repo',
  40. config={},
  41. local_borg_version='1.2.3',
  42. list_arguments=flexmock(archive=None, paths=None, json=False),
  43. global_arguments=flexmock(),
  44. )
  45. assert command == ('borg', 'list', '--debug', '--show-rc', 'repo')
  46. def test_make_list_command_includes_json_but_not_debug():
  47. insert_logging_mock(logging.DEBUG)
  48. flexmock(module.flags).should_receive('make_flags').and_return(())
  49. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
  50. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  51. command = module.make_list_command(
  52. repository_path='repo',
  53. config={},
  54. local_borg_version='1.2.3',
  55. list_arguments=flexmock(archive=None, paths=None, json=True),
  56. global_arguments=flexmock(),
  57. )
  58. assert command == ('borg', 'list', '--json', 'repo')
  59. def test_make_list_command_includes_json():
  60. flexmock(module.flags).should_receive('make_flags').and_return(())
  61. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--json',))
  62. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  63. command = module.make_list_command(
  64. repository_path='repo',
  65. config={},
  66. local_borg_version='1.2.3',
  67. list_arguments=flexmock(archive=None, paths=None, json=True),
  68. global_arguments=flexmock(),
  69. )
  70. assert command == ('borg', 'list', '--json', 'repo')
  71. def test_make_list_command_includes_log_json():
  72. flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return(
  73. ('--log-json',),
  74. )
  75. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  76. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  77. command = module.make_list_command(
  78. repository_path='repo',
  79. config={'log_json': True},
  80. local_borg_version='1.2.3',
  81. list_arguments=flexmock(archive=None, paths=None, json=False),
  82. global_arguments=flexmock(),
  83. )
  84. assert command == ('borg', 'list', '--log-json', 'repo')
  85. def test_make_list_command_includes_lock_wait():
  86. flexmock(module.flags).should_receive('make_flags').and_return(()).and_return(()).and_return(
  87. ('--lock-wait', '5'),
  88. )
  89. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  90. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  91. command = module.make_list_command(
  92. repository_path='repo',
  93. config={'lock_wait': 5},
  94. local_borg_version='1.2.3',
  95. list_arguments=flexmock(archive=None, paths=None, json=False),
  96. global_arguments=flexmock(),
  97. )
  98. assert command == ('borg', 'list', '--lock-wait', '5', 'repo')
  99. def test_make_list_command_includes_extra_borg_options():
  100. flexmock(module.flags).should_receive('make_flags').and_return(())
  101. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  102. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  103. command = module.make_list_command(
  104. repository_path='repo',
  105. config={'extra_borg_options': {'list': '--extra "value with space"'}},
  106. local_borg_version='1.2.3',
  107. list_arguments=flexmock(archive=None, paths=None, json=False),
  108. global_arguments=flexmock(),
  109. )
  110. assert command == ('borg', 'list', '--extra', 'value with space', 'repo')
  111. def test_make_list_command_includes_archive():
  112. flexmock(module.flags).should_receive('make_flags').and_return(())
  113. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  114. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  115. ('repo::archive',),
  116. )
  117. command = module.make_list_command(
  118. repository_path='repo',
  119. config={},
  120. local_borg_version='1.2.3',
  121. list_arguments=flexmock(archive='archive', paths=None, json=False),
  122. global_arguments=flexmock(),
  123. )
  124. assert command == ('borg', 'list', 'repo::archive')
  125. def test_make_list_command_includes_archive_and_path():
  126. flexmock(module.flags).should_receive('make_flags').and_return(())
  127. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  128. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  129. ('repo::archive',),
  130. )
  131. command = module.make_list_command(
  132. repository_path='repo',
  133. config={},
  134. local_borg_version='1.2.3',
  135. list_arguments=flexmock(archive='archive', paths=['var/lib'], json=False),
  136. global_arguments=flexmock(),
  137. )
  138. assert command == ('borg', 'list', 'repo::archive', 'var/lib')
  139. def test_make_list_command_includes_local_path():
  140. flexmock(module.flags).should_receive('make_flags').and_return(())
  141. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  142. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  143. command = module.make_list_command(
  144. repository_path='repo',
  145. config={},
  146. local_borg_version='1.2.3',
  147. list_arguments=flexmock(archive=None, paths=None, json=False),
  148. global_arguments=flexmock(),
  149. local_path='borg2',
  150. )
  151. assert command == ('borg2', 'list', 'repo')
  152. def test_make_list_command_includes_remote_path():
  153. flexmock(module.flags).should_receive('make_flags').and_return(())
  154. flexmock(module.flags).should_receive('make_flags').with_args(
  155. 'remote-path',
  156. 'borg2',
  157. ).and_return(('--remote-path', 'borg2'))
  158. flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return(
  159. ('--log-json'),
  160. )
  161. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  162. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  163. command = module.make_list_command(
  164. repository_path='repo',
  165. config={},
  166. local_borg_version='1.2.3',
  167. list_arguments=flexmock(archive=None, paths=None, json=False),
  168. global_arguments=flexmock(),
  169. remote_path='borg2',
  170. )
  171. assert command == ('borg', 'list', '--remote-path', 'borg2', 'repo')
  172. def test_make_list_command_includes_umask():
  173. flexmock(module.flags).should_receive('make_flags').replace_with(
  174. lambda name, value: (f'--{name}', value) if value else (),
  175. )
  176. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  177. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  178. command = module.make_list_command(
  179. repository_path='repo',
  180. config={'umask': '077'},
  181. local_borg_version='1.2.3',
  182. list_arguments=flexmock(archive=None, paths=None, json=False),
  183. global_arguments=flexmock(),
  184. )
  185. assert command == ('borg', 'list', '--umask', '077', 'repo')
  186. def test_make_list_command_includes_short():
  187. flexmock(module.flags).should_receive('make_flags').and_return(())
  188. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--short',))
  189. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  190. command = module.make_list_command(
  191. repository_path='repo',
  192. config={},
  193. local_borg_version='1.2.3',
  194. list_arguments=flexmock(archive=None, paths=None, json=False, short=True),
  195. global_arguments=flexmock(),
  196. )
  197. assert command == ('borg', 'list', '--short', 'repo')
  198. @pytest.mark.parametrize(
  199. 'argument_name',
  200. (
  201. 'prefix',
  202. 'match_archives',
  203. 'sort_by',
  204. 'first',
  205. 'last',
  206. 'exclude',
  207. 'exclude_from',
  208. 'pattern',
  209. 'patterns_from',
  210. ),
  211. )
  212. def test_make_list_command_includes_additional_flags(argument_name):
  213. flexmock(module.flags).should_receive('make_flags').and_return(())
  214. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
  215. (f"--{argument_name.replace('_', '-')}", 'value'),
  216. )
  217. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  218. command = module.make_list_command(
  219. repository_path='repo',
  220. config={},
  221. local_borg_version='1.2.3',
  222. list_arguments=flexmock(
  223. archive=None,
  224. paths=None,
  225. json=False,
  226. find_paths=None,
  227. format=None,
  228. **{argument_name: 'value'},
  229. ),
  230. global_arguments=flexmock(),
  231. )
  232. assert command == ('borg', 'list', '--' + argument_name.replace('_', '-'), 'value', 'repo')
  233. def test_make_find_paths_considers_none_as_empty_paths():
  234. assert module.make_find_paths(None) == ()
  235. def test_make_find_paths_passes_through_patterns():
  236. find_paths = (
  237. 'fm:*',
  238. 'sh:**/*.txt',
  239. 're:^.*$',
  240. 'pp:root/somedir',
  241. 'pf:root/foo.txt',
  242. 'R /',
  243. 'r /',
  244. 'p /',
  245. 'P /',
  246. '+ /',
  247. '- /',
  248. '! /',
  249. )
  250. assert module.make_find_paths(find_paths) == find_paths
  251. def test_make_find_paths_adds_globs_to_path_fragments():
  252. assert module.make_find_paths(('foo.txt',)) == ('sh:**/*foo.txt*/**',)
  253. def test_capture_archive_listing_does_not_raise():
  254. flexmock(module.environment).should_receive('make_environment')
  255. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  256. flexmock(module).should_receive('execute_command_and_capture_output').and_return('')
  257. flexmock(module).should_receive('make_list_command')
  258. module.capture_archive_listing(
  259. repository_path='repo',
  260. archive='archive',
  261. config={},
  262. local_borg_version=flexmock(),
  263. global_arguments=flexmock(),
  264. )
  265. def test_list_archive_calls_borg_with_flags():
  266. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  267. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  268. flexmock(module.logger).answer = lambda message: None
  269. list_arguments = argparse.Namespace(
  270. archive='archive',
  271. paths=None,
  272. json=False,
  273. find_paths=None,
  274. prefix=None,
  275. match_archives=None,
  276. sort_by=None,
  277. first=None,
  278. last=None,
  279. )
  280. global_arguments = flexmock()
  281. flexmock(module.feature).should_receive('available').and_return(False)
  282. flexmock(module).should_receive('make_list_command').with_args(
  283. repository_path='repo',
  284. config={},
  285. local_borg_version='1.2.3',
  286. list_arguments=list_arguments,
  287. global_arguments=global_arguments,
  288. local_path='borg',
  289. remote_path=None,
  290. ).and_return(('borg', 'list', 'repo::archive'))
  291. flexmock(module).should_receive('make_find_paths').and_return(())
  292. flexmock(module.environment).should_receive('make_environment')
  293. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  294. flexmock(module).should_receive('execute_command').with_args(
  295. ('borg', 'list', 'repo::archive'),
  296. output_log_level=module.borgmatic.logger.ANSWER,
  297. environment=None,
  298. working_directory=None,
  299. borg_local_path='borg',
  300. borg_exit_codes=None,
  301. ).once()
  302. module.list_archive(
  303. repository_path='repo',
  304. config={},
  305. local_borg_version='1.2.3',
  306. list_arguments=list_arguments,
  307. global_arguments=global_arguments,
  308. )
  309. def test_list_archive_with_archive_and_json_errors():
  310. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  311. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  312. flexmock(module.logger).answer = lambda message: None
  313. list_arguments = argparse.Namespace(archive='archive', paths=None, json=True, find_paths=None)
  314. flexmock(module.feature).should_receive('available').and_return(False)
  315. with pytest.raises(ValueError):
  316. module.list_archive(
  317. repository_path='repo',
  318. config={},
  319. local_borg_version='1.2.3',
  320. list_arguments=list_arguments,
  321. global_arguments=flexmock(),
  322. )
  323. def test_list_archive_calls_borg_with_local_path():
  324. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  325. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  326. flexmock(module.logger).answer = lambda message: None
  327. list_arguments = argparse.Namespace(
  328. archive='archive',
  329. paths=None,
  330. json=False,
  331. find_paths=None,
  332. prefix=None,
  333. match_archives=None,
  334. sort_by=None,
  335. first=None,
  336. last=None,
  337. )
  338. global_arguments = flexmock()
  339. flexmock(module.feature).should_receive('available').and_return(False)
  340. flexmock(module).should_receive('make_list_command').with_args(
  341. repository_path='repo',
  342. config={},
  343. local_borg_version='1.2.3',
  344. list_arguments=list_arguments,
  345. global_arguments=global_arguments,
  346. local_path='borg2',
  347. remote_path=None,
  348. ).and_return(('borg2', 'list', 'repo::archive'))
  349. flexmock(module).should_receive('make_find_paths').and_return(())
  350. flexmock(module.environment).should_receive('make_environment')
  351. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  352. flexmock(module).should_receive('execute_command').with_args(
  353. ('borg2', 'list', 'repo::archive'),
  354. output_log_level=module.borgmatic.logger.ANSWER,
  355. environment=None,
  356. working_directory=None,
  357. borg_local_path='borg2',
  358. borg_exit_codes=None,
  359. ).once()
  360. module.list_archive(
  361. repository_path='repo',
  362. config={},
  363. local_borg_version='1.2.3',
  364. list_arguments=list_arguments,
  365. global_arguments=global_arguments,
  366. local_path='borg2',
  367. )
  368. def test_list_archive_calls_borg_using_exit_codes():
  369. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  370. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  371. flexmock(module.logger).answer = lambda message: None
  372. list_arguments = argparse.Namespace(
  373. archive='archive',
  374. paths=None,
  375. json=False,
  376. find_paths=None,
  377. prefix=None,
  378. match_archives=None,
  379. sort_by=None,
  380. first=None,
  381. last=None,
  382. )
  383. global_arguments = flexmock()
  384. flexmock(module.feature).should_receive('available').and_return(False)
  385. borg_exit_codes = flexmock()
  386. flexmock(module).should_receive('make_list_command').with_args(
  387. repository_path='repo',
  388. config={'borg_exit_codes': borg_exit_codes},
  389. local_borg_version='1.2.3',
  390. list_arguments=list_arguments,
  391. global_arguments=global_arguments,
  392. local_path='borg',
  393. remote_path=None,
  394. ).and_return(('borg', 'list', 'repo::archive'))
  395. flexmock(module).should_receive('make_find_paths').and_return(())
  396. flexmock(module.environment).should_receive('make_environment')
  397. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  398. flexmock(module).should_receive('execute_command').with_args(
  399. ('borg', 'list', 'repo::archive'),
  400. output_log_level=module.borgmatic.logger.ANSWER,
  401. environment=None,
  402. working_directory=None,
  403. borg_local_path='borg',
  404. borg_exit_codes=borg_exit_codes,
  405. ).once()
  406. module.list_archive(
  407. repository_path='repo',
  408. config={'borg_exit_codes': borg_exit_codes},
  409. local_borg_version='1.2.3',
  410. list_arguments=list_arguments,
  411. global_arguments=global_arguments,
  412. )
  413. def test_list_archive_calls_borg_multiple_times_with_find_paths():
  414. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  415. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  416. flexmock(module.logger).answer = lambda message: None
  417. glob_paths = ('**/*foo.txt*/**',)
  418. list_arguments = argparse.Namespace(
  419. archive=None,
  420. json=False,
  421. find_paths=['foo.txt'],
  422. prefix=None,
  423. match_archives=None,
  424. sort_by=None,
  425. first=None,
  426. last=None,
  427. )
  428. flexmock(module.feature).should_receive('available').and_return(False)
  429. flexmock(module.repo_list).should_receive('make_repo_list_command').and_return(
  430. ('borg', 'list', 'repo'),
  431. )
  432. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  433. flexmock(module).should_receive('execute_command_and_capture_output').with_args(
  434. ('borg', 'list', 'repo'),
  435. environment=None,
  436. working_directory=None,
  437. borg_local_path='borg',
  438. borg_exit_codes=None,
  439. ).and_return('archive1\narchive2').once()
  440. flexmock(module).should_receive('make_list_command').and_return(
  441. ('borg', 'list', 'repo::archive1'),
  442. ).and_return(('borg', 'list', 'repo::archive2'))
  443. flexmock(module).should_receive('make_find_paths').and_return(glob_paths)
  444. flexmock(module.environment).should_receive('make_environment')
  445. flexmock(module).should_receive('execute_command').with_args(
  446. ('borg', 'list', 'repo::archive1', *glob_paths),
  447. output_log_level=module.borgmatic.logger.ANSWER,
  448. environment=None,
  449. working_directory=None,
  450. borg_local_path='borg',
  451. borg_exit_codes=None,
  452. ).once()
  453. flexmock(module).should_receive('execute_command').with_args(
  454. ('borg', 'list', 'repo::archive2', *glob_paths),
  455. output_log_level=module.borgmatic.logger.ANSWER,
  456. environment=None,
  457. working_directory=None,
  458. borg_local_path='borg',
  459. borg_exit_codes=None,
  460. ).once()
  461. module.list_archive(
  462. repository_path='repo',
  463. config={},
  464. local_borg_version='1.2.3',
  465. list_arguments=list_arguments,
  466. global_arguments=flexmock(),
  467. )
  468. def test_list_archive_calls_borg_with_archive():
  469. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  470. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  471. flexmock(module.logger).answer = lambda message: None
  472. list_arguments = argparse.Namespace(
  473. archive='archive',
  474. paths=None,
  475. json=False,
  476. find_paths=None,
  477. prefix=None,
  478. match_archives=None,
  479. sort_by=None,
  480. first=None,
  481. last=None,
  482. )
  483. global_arguments = flexmock()
  484. flexmock(module.feature).should_receive('available').and_return(False)
  485. flexmock(module).should_receive('make_list_command').with_args(
  486. repository_path='repo',
  487. config={},
  488. local_borg_version='1.2.3',
  489. list_arguments=list_arguments,
  490. global_arguments=global_arguments,
  491. local_path='borg',
  492. remote_path=None,
  493. ).and_return(('borg', 'list', 'repo::archive'))
  494. flexmock(module).should_receive('make_find_paths').and_return(())
  495. flexmock(module.environment).should_receive('make_environment')
  496. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  497. flexmock(module).should_receive('execute_command').with_args(
  498. ('borg', 'list', 'repo::archive'),
  499. output_log_level=module.borgmatic.logger.ANSWER,
  500. environment=None,
  501. working_directory=None,
  502. borg_local_path='borg',
  503. borg_exit_codes=None,
  504. ).once()
  505. module.list_archive(
  506. repository_path='repo',
  507. config={},
  508. local_borg_version='1.2.3',
  509. list_arguments=list_arguments,
  510. global_arguments=global_arguments,
  511. )
  512. def test_list_archive_without_archive_delegates_to_list_repository():
  513. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  514. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  515. flexmock(module.logger).answer = lambda message: None
  516. list_arguments = argparse.Namespace(
  517. archive=None,
  518. short=None,
  519. format=None,
  520. json=None,
  521. prefix=None,
  522. match_archives=None,
  523. sort_by=None,
  524. first=None,
  525. last=None,
  526. find_paths=None,
  527. )
  528. flexmock(module.feature).should_receive('available').and_return(False)
  529. flexmock(module.repo_list).should_receive('list_repository')
  530. flexmock(module.environment).should_receive('make_environment').never()
  531. flexmock(module).should_receive('execute_command').never()
  532. module.list_archive(
  533. repository_path='repo',
  534. config={},
  535. local_borg_version='1.2.3',
  536. list_arguments=list_arguments,
  537. global_arguments=flexmock(),
  538. )
  539. def test_list_archive_with_borg_features_without_archive_delegates_to_list_repository():
  540. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  541. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  542. flexmock(module.logger).answer = lambda message: None
  543. list_arguments = argparse.Namespace(
  544. archive=None,
  545. short=None,
  546. format=None,
  547. json=None,
  548. prefix=None,
  549. match_archives=None,
  550. sort_by=None,
  551. first=None,
  552. last=None,
  553. find_paths=None,
  554. )
  555. flexmock(module.feature).should_receive('available').and_return(True)
  556. flexmock(module.repo_list).should_receive('list_repository')
  557. flexmock(module.environment).should_receive('make_environment').never()
  558. flexmock(module).should_receive('execute_command').never()
  559. module.list_archive(
  560. repository_path='repo',
  561. config={},
  562. local_borg_version='1.2.3',
  563. list_arguments=list_arguments,
  564. global_arguments=flexmock(),
  565. )
  566. @pytest.mark.parametrize(
  567. 'archive_filter_flag',
  568. (
  569. 'prefix',
  570. 'match_archives',
  571. 'sort_by',
  572. 'first',
  573. 'last',
  574. ),
  575. )
  576. def test_list_archive_with_archive_ignores_archive_filter_flag(
  577. archive_filter_flag,
  578. ):
  579. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  580. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  581. flexmock(module.logger).answer = lambda message: None
  582. global_arguments = flexmock()
  583. default_filter_flags = {
  584. 'prefix': None,
  585. 'match_archives': None,
  586. 'sort_by': None,
  587. 'first': None,
  588. 'last': None,
  589. }
  590. altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} # noqa: PIE800
  591. flexmock(module.feature).should_receive('available').with_args(
  592. module.feature.Feature.REPO_LIST,
  593. '1.2.3',
  594. ).and_return(False)
  595. flexmock(module).should_receive('make_list_command').with_args(
  596. repository_path='repo',
  597. config={},
  598. local_borg_version='1.2.3',
  599. list_arguments=argparse.Namespace(
  600. archive='archive',
  601. paths=None,
  602. json=False,
  603. find_paths=None,
  604. **default_filter_flags,
  605. ),
  606. global_arguments=global_arguments,
  607. local_path='borg',
  608. remote_path=None,
  609. ).and_return(('borg', 'list', 'repo::archive'))
  610. flexmock(module).should_receive('make_find_paths').and_return(())
  611. flexmock(module.environment).should_receive('make_environment')
  612. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  613. flexmock(module).should_receive('execute_command').with_args(
  614. ('borg', 'list', 'repo::archive'),
  615. output_log_level=module.borgmatic.logger.ANSWER,
  616. environment=None,
  617. working_directory=None,
  618. borg_local_path='borg',
  619. borg_exit_codes=None,
  620. ).once()
  621. module.list_archive(
  622. repository_path='repo',
  623. config={},
  624. local_borg_version='1.2.3',
  625. list_arguments=argparse.Namespace(
  626. archive='archive',
  627. paths=None,
  628. json=False,
  629. find_paths=None,
  630. **altered_filter_flags,
  631. ),
  632. global_arguments=global_arguments,
  633. )
  634. @pytest.mark.parametrize(
  635. 'archive_filter_flag',
  636. (
  637. 'prefix',
  638. 'match_archives',
  639. 'sort_by',
  640. 'first',
  641. 'last',
  642. ),
  643. )
  644. def test_list_archive_with_find_paths_allows_archive_filter_flag_but_only_passes_it_to_repo_list(
  645. archive_filter_flag,
  646. ):
  647. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  648. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  649. flexmock(module.logger).answer = lambda message: None
  650. default_filter_flags = {
  651. 'prefix': None,
  652. 'match_archives': None,
  653. 'sort_by': None,
  654. 'first': None,
  655. 'last': None,
  656. }
  657. altered_filter_flags = {**default_filter_flags, **{archive_filter_flag: 'foo'}} # noqa: PIE800
  658. glob_paths = ('**/*foo.txt*/**',)
  659. global_arguments = flexmock()
  660. flexmock(module.feature).should_receive('available').and_return(True)
  661. flexmock(module.repo_list).should_receive('make_repo_list_command').with_args(
  662. repository_path='repo',
  663. config={},
  664. local_borg_version='1.2.3',
  665. repo_list_arguments=argparse.Namespace(
  666. repository='repo',
  667. short=True,
  668. format=None,
  669. json=None,
  670. **altered_filter_flags,
  671. ),
  672. global_arguments=global_arguments,
  673. local_path='borg',
  674. remote_path=None,
  675. ).and_return(('borg', 'repo-list', '--repo', 'repo'))
  676. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  677. flexmock(module).should_receive('execute_command_and_capture_output').with_args(
  678. ('borg', 'repo-list', '--repo', 'repo'),
  679. environment=None,
  680. working_directory=None,
  681. borg_local_path='borg',
  682. borg_exit_codes=None,
  683. ).and_return('archive1\narchive2').once()
  684. flexmock(module).should_receive('make_list_command').with_args(
  685. repository_path='repo',
  686. config={},
  687. local_borg_version='1.2.3',
  688. list_arguments=argparse.Namespace(
  689. repository='repo',
  690. archive='archive1',
  691. paths=None,
  692. short=True,
  693. format=None,
  694. json=None,
  695. find_paths=['foo.txt'],
  696. **default_filter_flags,
  697. ),
  698. global_arguments=global_arguments,
  699. local_path='borg',
  700. remote_path=None,
  701. ).and_return(('borg', 'list', '--repo', 'repo', 'archive1'))
  702. flexmock(module).should_receive('make_list_command').with_args(
  703. repository_path='repo',
  704. config={},
  705. local_borg_version='1.2.3',
  706. list_arguments=argparse.Namespace(
  707. repository='repo',
  708. archive='archive2',
  709. paths=None,
  710. short=True,
  711. format=None,
  712. json=None,
  713. find_paths=['foo.txt'],
  714. **default_filter_flags,
  715. ),
  716. global_arguments=global_arguments,
  717. local_path='borg',
  718. remote_path=None,
  719. ).and_return(('borg', 'list', '--repo', 'repo', 'archive2'))
  720. flexmock(module).should_receive('make_find_paths').and_return(glob_paths)
  721. flexmock(module.environment).should_receive('make_environment')
  722. flexmock(module).should_receive('execute_command').with_args(
  723. ('borg', 'list', '--repo', 'repo', 'archive1', *glob_paths),
  724. output_log_level=module.borgmatic.logger.ANSWER,
  725. environment=None,
  726. working_directory=None,
  727. borg_local_path='borg',
  728. borg_exit_codes=None,
  729. ).once()
  730. flexmock(module).should_receive('execute_command').with_args(
  731. ('borg', 'list', '--repo', 'repo', 'archive2', *glob_paths),
  732. output_log_level=module.borgmatic.logger.ANSWER,
  733. environment=None,
  734. working_directory=None,
  735. borg_local_path='borg',
  736. borg_exit_codes=None,
  737. ).once()
  738. module.list_archive(
  739. repository_path='repo',
  740. config={},
  741. local_borg_version='1.2.3',
  742. list_arguments=argparse.Namespace(
  743. repository='repo',
  744. archive=None,
  745. paths=None,
  746. short=True,
  747. format=None,
  748. json=None,
  749. find_paths=['foo.txt'],
  750. **altered_filter_flags,
  751. ),
  752. global_arguments=global_arguments,
  753. )
  754. def test_list_archive_calls_borg_with_working_directory():
  755. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  756. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  757. flexmock(module.logger).answer = lambda message: None
  758. list_arguments = argparse.Namespace(
  759. archive='archive',
  760. paths=None,
  761. json=False,
  762. find_paths=None,
  763. prefix=None,
  764. match_archives=None,
  765. sort_by=None,
  766. first=None,
  767. last=None,
  768. )
  769. global_arguments = flexmock()
  770. flexmock(module.feature).should_receive('available').and_return(False)
  771. flexmock(module).should_receive('make_list_command').with_args(
  772. repository_path='repo',
  773. config={'working_directory': '/working/dir'},
  774. local_borg_version='1.2.3',
  775. list_arguments=list_arguments,
  776. global_arguments=global_arguments,
  777. local_path='borg',
  778. remote_path=None,
  779. ).and_return(('borg', 'list', 'repo::archive'))
  780. flexmock(module).should_receive('make_find_paths').and_return(())
  781. flexmock(module.environment).should_receive('make_environment')
  782. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
  783. '/working/dir',
  784. )
  785. flexmock(module).should_receive('execute_command').with_args(
  786. ('borg', 'list', 'repo::archive'),
  787. output_log_level=module.borgmatic.logger.ANSWER,
  788. environment=None,
  789. working_directory='/working/dir',
  790. borg_local_path='borg',
  791. borg_exit_codes=None,
  792. ).once()
  793. module.list_archive(
  794. repository_path='repo',
  795. config={'working_directory': '/working/dir'},
  796. local_borg_version='1.2.3',
  797. list_arguments=list_arguments,
  798. global_arguments=global_arguments,
  799. )