test_prune.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. import logging
  2. from flexmock import flexmock
  3. from borgmatic.borg import prune as module
  4. from ..test_verbosity import insert_logging_mock
  5. def insert_execute_command_mock(
  6. prune_command,
  7. output_log_level,
  8. working_directory=None,
  9. borg_exit_codes=None,
  10. ):
  11. flexmock(module.environment).should_receive('make_environment')
  12. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
  13. working_directory,
  14. )
  15. flexmock(module).should_receive('execute_command').with_args(
  16. prune_command,
  17. output_log_level=output_log_level,
  18. environment=None,
  19. working_directory=working_directory,
  20. borg_local_path=prune_command[0],
  21. borg_exit_codes=borg_exit_codes,
  22. ).once()
  23. BASE_PRUNE_FLAGS = ('--keep-daily', '1', '--keep-weekly', '2', '--keep-monthly', '3')
  24. def test_make_prune_flags_returns_flags_from_config():
  25. config = {
  26. 'keep_daily': 1,
  27. 'keep_weekly': 2,
  28. 'keep_monthly': 3,
  29. }
  30. flexmock(module.feature).should_receive('available').and_return(True)
  31. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  32. result = module.make_prune_flags(
  33. config,
  34. flexmock(match_archives=None),
  35. local_borg_version='1.2.3',
  36. )
  37. assert result == BASE_PRUNE_FLAGS
  38. def test_make_prune_flags_with_keep_13weekly_and_keep_3monthly():
  39. config = {
  40. 'keep_13weekly': 4,
  41. 'keep_3monthly': 5,
  42. }
  43. flexmock(module.feature).should_receive('available').and_return(True)
  44. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  45. result = module.make_prune_flags(
  46. config,
  47. flexmock(match_archives=None),
  48. local_borg_version='1.2.3',
  49. )
  50. expected = (
  51. '--keep-13weekly',
  52. '4',
  53. '--keep-3monthly',
  54. '5',
  55. )
  56. assert result == expected
  57. def test_make_prune_flags_accepts_prefix_with_placeholders():
  58. config = {
  59. 'keep_daily': 1,
  60. 'prefix': 'Documents_{hostname}-{now}',
  61. }
  62. flexmock(module.feature).should_receive('available').and_return(True)
  63. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  64. result = module.make_prune_flags(
  65. config,
  66. flexmock(match_archives=None),
  67. local_borg_version='1.2.3',
  68. )
  69. expected = (
  70. '--keep-daily',
  71. '1',
  72. '--match-archives',
  73. 'sh:Documents_{hostname}-{now}*',
  74. )
  75. assert result == expected
  76. def test_make_prune_flags_with_prefix_without_borg_features_uses_glob_archives():
  77. config = {
  78. 'keep_daily': 1,
  79. 'prefix': 'Documents_{hostname}-{now}',
  80. }
  81. flexmock(module.feature).should_receive('available').and_return(False)
  82. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  83. result = module.make_prune_flags(
  84. config,
  85. flexmock(match_archives=None),
  86. local_borg_version='1.2.3',
  87. )
  88. expected = (
  89. '--keep-daily',
  90. '1',
  91. '--glob-archives',
  92. 'Documents_{hostname}-{now}*',
  93. )
  94. assert result == expected
  95. def test_make_prune_flags_prefers_prefix_to_archive_name_format():
  96. config = {
  97. 'archive_name_format': 'bar-{now}',
  98. 'keep_daily': 1,
  99. 'prefix': 'bar-',
  100. }
  101. flexmock(module.feature).should_receive('available').and_return(True)
  102. flexmock(module.flags).should_receive('make_match_archives_flags').never()
  103. result = module.make_prune_flags(
  104. config,
  105. flexmock(match_archives=None),
  106. local_borg_version='1.2.3',
  107. )
  108. expected = (
  109. '--keep-daily',
  110. '1',
  111. '--match-archives',
  112. 'sh:bar-*',
  113. )
  114. assert result == expected
  115. def test_make_prune_flags_without_prefix_uses_archive_name_format_instead():
  116. config = {
  117. 'archive_name_format': 'bar-{now}',
  118. 'keep_daily': 1,
  119. 'prefix': None,
  120. }
  121. flexmock(module.feature).should_receive('available').and_return(True)
  122. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  123. None,
  124. 'bar-{now}',
  125. '1.2.3',
  126. ).and_return(('--match-archives', 'sh:bar-*')).once()
  127. result = module.make_prune_flags(
  128. config,
  129. flexmock(match_archives=None),
  130. local_borg_version='1.2.3',
  131. )
  132. expected = (
  133. '--keep-daily',
  134. '1',
  135. '--match-archives',
  136. 'sh:bar-*',
  137. )
  138. assert result == expected
  139. def test_make_prune_flags_without_prefix_uses_match_archives_option():
  140. config = {
  141. 'archive_name_format': 'bar-{now}',
  142. 'match_archives': 'foo*',
  143. 'keep_daily': 1,
  144. 'prefix': None,
  145. }
  146. flexmock(module.feature).should_receive('available').and_return(True)
  147. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  148. 'foo*',
  149. 'bar-{now}',
  150. '1.2.3',
  151. ).and_return(('--match-archives', 'sh:bar-*')).once()
  152. result = module.make_prune_flags(
  153. config,
  154. flexmock(match_archives=None),
  155. local_borg_version='1.2.3',
  156. )
  157. expected = (
  158. '--keep-daily',
  159. '1',
  160. '--match-archives',
  161. 'sh:bar-*',
  162. )
  163. assert result == expected
  164. def test_make_prune_flags_ignores_keep_exclude_tags_in_config():
  165. config = {
  166. 'keep_daily': 1,
  167. 'keep_exclude_tags': True,
  168. }
  169. flexmock(module.feature).should_receive('available').and_return(True)
  170. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  171. result = module.make_prune_flags(
  172. config,
  173. flexmock(match_archives=None),
  174. local_borg_version='1.2.3',
  175. )
  176. assert result == ('--keep-daily', '1')
  177. PRUNE_COMMAND = ('borg', 'prune', '--keep-daily', '1', '--keep-weekly', '2', '--keep-monthly', '3')
  178. def test_prune_archives_calls_borg_with_flags():
  179. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  180. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  181. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  182. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  183. flexmock(module.feature).should_receive('available').with_args(
  184. module.feature.Feature.NO_PRUNE_STATS,
  185. '1.2.3',
  186. ).and_return(False)
  187. insert_execute_command_mock((*PRUNE_COMMAND, 'repo'), logging.INFO)
  188. prune_arguments = flexmock(statistics=False, list_details=False)
  189. module.prune_archives(
  190. dry_run=False,
  191. repository_path='repo',
  192. config={},
  193. local_borg_version='1.2.3',
  194. global_arguments=flexmock(),
  195. prune_arguments=prune_arguments,
  196. )
  197. def test_prune_archives_with_log_info_calls_borg_with_info_flag():
  198. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  199. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  200. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  201. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  202. flexmock(module.feature).should_receive('available').with_args(
  203. module.feature.Feature.NO_PRUNE_STATS,
  204. '1.2.3',
  205. ).and_return(False)
  206. insert_execute_command_mock((*PRUNE_COMMAND, '--info', 'repo'), logging.INFO)
  207. insert_logging_mock(logging.INFO)
  208. prune_arguments = flexmock(statistics=False, list_details=False)
  209. module.prune_archives(
  210. repository_path='repo',
  211. config={},
  212. dry_run=False,
  213. local_borg_version='1.2.3',
  214. global_arguments=flexmock(),
  215. prune_arguments=prune_arguments,
  216. )
  217. def test_prune_archives_with_log_debug_calls_borg_with_debug_flag():
  218. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  219. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  220. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  221. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  222. flexmock(module.feature).should_receive('available').with_args(
  223. module.feature.Feature.NO_PRUNE_STATS,
  224. '1.2.3',
  225. ).and_return(False)
  226. insert_execute_command_mock((*PRUNE_COMMAND, '--debug', '--show-rc', 'repo'), logging.INFO)
  227. insert_logging_mock(logging.DEBUG)
  228. prune_arguments = flexmock(statistics=False, list_details=False)
  229. module.prune_archives(
  230. repository_path='repo',
  231. config={},
  232. dry_run=False,
  233. local_borg_version='1.2.3',
  234. global_arguments=flexmock(),
  235. prune_arguments=prune_arguments,
  236. )
  237. def test_prune_archives_with_dry_run_calls_borg_with_dry_run_flag():
  238. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  239. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  240. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  241. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  242. flexmock(module.feature).should_receive('available').with_args(
  243. module.feature.Feature.NO_PRUNE_STATS,
  244. '1.2.3',
  245. ).and_return(False)
  246. insert_execute_command_mock((*PRUNE_COMMAND, '--dry-run', 'repo'), logging.INFO)
  247. prune_arguments = flexmock(statistics=False, list_details=False)
  248. module.prune_archives(
  249. repository_path='repo',
  250. config={},
  251. dry_run=True,
  252. local_borg_version='1.2.3',
  253. global_arguments=flexmock(),
  254. prune_arguments=prune_arguments,
  255. )
  256. def test_prune_archives_with_local_path_calls_borg_via_local_path():
  257. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  258. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  259. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  260. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  261. flexmock(module.feature).should_receive('available').with_args(
  262. module.feature.Feature.NO_PRUNE_STATS,
  263. '1.2.3',
  264. ).and_return(False)
  265. insert_execute_command_mock(('borg1', *PRUNE_COMMAND[1:], 'repo'), logging.INFO)
  266. prune_arguments = flexmock(statistics=False, list_details=False)
  267. module.prune_archives(
  268. dry_run=False,
  269. repository_path='repo',
  270. config={},
  271. local_borg_version='1.2.3',
  272. global_arguments=flexmock(),
  273. local_path='borg1',
  274. prune_arguments=prune_arguments,
  275. )
  276. def test_prune_archives_with_exit_codes_calls_borg_using_them():
  277. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  278. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  279. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  280. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  281. flexmock(module.feature).should_receive('available').with_args(
  282. module.feature.Feature.NO_PRUNE_STATS,
  283. '1.2.3',
  284. ).and_return(False)
  285. borg_exit_codes = flexmock()
  286. insert_execute_command_mock(
  287. ('borg', *PRUNE_COMMAND[1:], 'repo'),
  288. logging.INFO,
  289. borg_exit_codes=borg_exit_codes,
  290. )
  291. prune_arguments = flexmock(statistics=False, list_details=False)
  292. module.prune_archives(
  293. dry_run=False,
  294. repository_path='repo',
  295. config={'borg_exit_codes': borg_exit_codes},
  296. local_borg_version='1.2.3',
  297. global_arguments=flexmock(),
  298. prune_arguments=prune_arguments,
  299. )
  300. def test_prune_archives_with_remote_path_calls_borg_with_remote_path_flags():
  301. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  302. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  303. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  304. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  305. flexmock(module.feature).should_receive('available').with_args(
  306. module.feature.Feature.NO_PRUNE_STATS,
  307. '1.2.3',
  308. ).and_return(False)
  309. insert_execute_command_mock((*PRUNE_COMMAND, '--remote-path', 'borg1', 'repo'), logging.INFO)
  310. prune_arguments = flexmock(statistics=False, list_details=False)
  311. module.prune_archives(
  312. dry_run=False,
  313. repository_path='repo',
  314. config={},
  315. local_borg_version='1.2.3',
  316. global_arguments=flexmock(),
  317. remote_path='borg1',
  318. prune_arguments=prune_arguments,
  319. )
  320. def test_prune_archives_with_stats_config_calls_borg_with_stats_flag():
  321. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  322. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  323. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  324. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  325. flexmock(module.feature).should_receive('available').with_args(
  326. module.feature.Feature.NO_PRUNE_STATS,
  327. '1.2.3',
  328. ).and_return(False)
  329. insert_execute_command_mock((*PRUNE_COMMAND, '--stats', 'repo'), module.borgmatic.logger.ANSWER)
  330. prune_arguments = flexmock(statistics=None, list_details=False)
  331. module.prune_archives(
  332. dry_run=False,
  333. repository_path='repo',
  334. config={'statistics': True},
  335. local_borg_version='1.2.3',
  336. global_arguments=flexmock(),
  337. prune_arguments=prune_arguments,
  338. )
  339. def test_prune_archives_with_list_config_calls_borg_with_list_flag():
  340. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  341. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  342. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  343. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  344. flexmock(module.feature).should_receive('available').with_args(
  345. module.feature.Feature.NO_PRUNE_STATS,
  346. '1.2.3',
  347. ).and_return(False)
  348. insert_execute_command_mock((*PRUNE_COMMAND, '--list', 'repo'), module.borgmatic.logger.ANSWER)
  349. prune_arguments = flexmock(statistics=False, list_details=None)
  350. module.prune_archives(
  351. dry_run=False,
  352. repository_path='repo',
  353. config={'list_details': True},
  354. local_borg_version='1.2.3',
  355. global_arguments=flexmock(),
  356. prune_arguments=prune_arguments,
  357. )
  358. def test_prune_archives_with_umask_calls_borg_with_umask_flags():
  359. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  360. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  361. config = {'umask': '077'}
  362. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  363. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  364. flexmock(module.feature).should_receive('available').with_args(
  365. module.feature.Feature.NO_PRUNE_STATS,
  366. '1.2.3',
  367. ).and_return(False)
  368. insert_execute_command_mock((*PRUNE_COMMAND, '--umask', '077', 'repo'), logging.INFO)
  369. prune_arguments = flexmock(statistics=False, list_details=False)
  370. module.prune_archives(
  371. dry_run=False,
  372. repository_path='repo',
  373. config=config,
  374. local_borg_version='1.2.3',
  375. global_arguments=flexmock(),
  376. prune_arguments=prune_arguments,
  377. )
  378. def test_prune_archives_with_log_json_calls_borg_with_log_json_flag():
  379. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  380. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  381. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  382. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  383. flexmock(module.feature).should_receive('available').with_args(
  384. module.feature.Feature.NO_PRUNE_STATS,
  385. '1.2.3',
  386. ).and_return(False)
  387. insert_execute_command_mock((*PRUNE_COMMAND, '--log-json', 'repo'), logging.INFO)
  388. prune_arguments = flexmock(statistics=False, list_details=False)
  389. module.prune_archives(
  390. dry_run=False,
  391. repository_path='repo',
  392. config={'log_json': True},
  393. local_borg_version='1.2.3',
  394. global_arguments=flexmock(),
  395. prune_arguments=prune_arguments,
  396. )
  397. def test_prune_archives_with_lock_wait_calls_borg_with_lock_wait_flags():
  398. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  399. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  400. config = {'lock_wait': 5}
  401. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  402. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  403. flexmock(module.feature).should_receive('available').with_args(
  404. module.feature.Feature.NO_PRUNE_STATS,
  405. '1.2.3',
  406. ).and_return(False)
  407. insert_execute_command_mock((*PRUNE_COMMAND, '--lock-wait', '5', 'repo'), logging.INFO)
  408. prune_arguments = flexmock(statistics=False, list_details=False)
  409. module.prune_archives(
  410. dry_run=False,
  411. repository_path='repo',
  412. config=config,
  413. local_borg_version='1.2.3',
  414. global_arguments=flexmock(),
  415. prune_arguments=prune_arguments,
  416. )
  417. def test_prune_archives_with_extra_borg_options_calls_borg_with_extra_options():
  418. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  419. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  420. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  421. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  422. flexmock(module.feature).should_receive('available').with_args(
  423. module.feature.Feature.NO_PRUNE_STATS,
  424. '1.2.3',
  425. ).and_return(False)
  426. insert_execute_command_mock(
  427. (*PRUNE_COMMAND, '--extra', '--options', 'value with space', 'repo'),
  428. logging.INFO,
  429. )
  430. prune_arguments = flexmock(statistics=False, list_details=False)
  431. module.prune_archives(
  432. dry_run=False,
  433. repository_path='repo',
  434. config={'extra_borg_options': {'prune': '--extra --options "value with space"'}},
  435. local_borg_version='1.2.3',
  436. global_arguments=flexmock(),
  437. prune_arguments=prune_arguments,
  438. )
  439. def test_prune_archives_with_date_based_matching_calls_borg_with_date_based_flags():
  440. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  441. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  442. flexmock(module.flags).should_receive('make_flags').and_return(())
  443. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  444. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  445. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
  446. (
  447. '--newer',
  448. '1d',
  449. '--newest',
  450. '1y',
  451. '--older',
  452. '1m',
  453. '--oldest',
  454. '1w',
  455. '--match-archives',
  456. None,
  457. ),
  458. )
  459. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  460. flexmock(module.feature).should_receive('available').with_args(
  461. module.feature.Feature.NO_PRUNE_STATS,
  462. '1.2.3',
  463. ).and_return(False)
  464. flexmock(module.environment).should_receive('make_environment')
  465. flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
  466. flexmock(module).should_receive('execute_command').with_args(
  467. (
  468. 'borg',
  469. 'prune',
  470. '--keep-daily',
  471. '1',
  472. '--keep-weekly',
  473. '2',
  474. '--keep-monthly',
  475. '3',
  476. '--newer',
  477. '1d',
  478. '--newest',
  479. '1y',
  480. '--older',
  481. '1m',
  482. '--oldest',
  483. '1w',
  484. '--match-archives',
  485. None,
  486. '--repo',
  487. 'repo',
  488. ),
  489. output_log_level=logging.INFO,
  490. environment=None,
  491. working_directory=None,
  492. borg_local_path='borg',
  493. borg_exit_codes=None,
  494. )
  495. prune_arguments = flexmock(
  496. statistics=False,
  497. list_details=False,
  498. newer='1d',
  499. newest='1y',
  500. older='1m',
  501. oldest='1w',
  502. )
  503. module.prune_archives(
  504. dry_run=False,
  505. repository_path='repo',
  506. config={},
  507. local_borg_version='1.2.3',
  508. global_arguments=flexmock(),
  509. prune_arguments=prune_arguments,
  510. )
  511. def test_prune_archives_calls_borg_with_working_directory():
  512. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  513. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  514. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  515. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  516. flexmock(module.feature).should_receive('available').with_args(
  517. module.feature.Feature.NO_PRUNE_STATS,
  518. '1.2.3',
  519. ).and_return(False)
  520. insert_execute_command_mock(
  521. (*PRUNE_COMMAND, 'repo'),
  522. logging.INFO,
  523. working_directory='/working/dir',
  524. )
  525. prune_arguments = flexmock(statistics=False, list_details=False)
  526. module.prune_archives(
  527. dry_run=False,
  528. repository_path='repo',
  529. config={'working_directory': '/working/dir'},
  530. local_borg_version='1.2.3',
  531. global_arguments=flexmock(),
  532. prune_arguments=prune_arguments,
  533. )
  534. def test_prune_archives_calls_borg_without_stats_when_feature_is_not_available():
  535. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  536. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  537. flexmock(module).should_receive('make_prune_flags').and_return(BASE_PRUNE_FLAGS)
  538. flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
  539. flexmock(module.feature).should_receive('available').with_args(
  540. module.feature.Feature.NO_PRUNE_STATS,
  541. '2.0.0b10',
  542. ).and_return(True)
  543. insert_execute_command_mock((*PRUNE_COMMAND, 'repo'), logging.ANSWER)
  544. prune_arguments = flexmock(statistics=True, list_details=False)
  545. module.prune_archives(
  546. dry_run=False,
  547. repository_path='repo',
  548. config={'statistics': True},
  549. local_borg_version='2.0.0b10',
  550. global_arguments=flexmock(),
  551. prune_arguments=prune_arguments,
  552. )