test_transfer.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. import logging
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic.borg import transfer as module
  5. from ..test_verbosity import insert_logging_mock
  6. def test_transfer_archives_calls_borg_with_flags():
  7. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  8. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  9. flexmock(module.flags).should_receive('make_flags').and_return(())
  10. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  11. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  12. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  13. flexmock(module.environment).should_receive('make_environment')
  14. flexmock(module).should_receive('execute_command').with_args(
  15. ('borg', 'transfer', '--repo', 'repo'),
  16. output_log_level=module.borgmatic.logger.ANSWER,
  17. output_file=None,
  18. borg_local_path='borg',
  19. extra_environment=None,
  20. )
  21. module.transfer_archives(
  22. dry_run=False,
  23. repository_path='repo',
  24. storage_config={},
  25. local_borg_version='2.3.4',
  26. transfer_arguments=flexmock(
  27. archive=None, progress=None, match_archives=None, source_repository=None
  28. ),
  29. global_arguments=flexmock(log_json=False),
  30. )
  31. def test_transfer_archives_with_dry_run_calls_borg_with_dry_run_flag():
  32. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  33. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  34. flexmock(module.flags).should_receive('make_flags').and_return(())
  35. flexmock(module.flags).should_receive('make_flags').with_args('dry-run', True).and_return(
  36. ('--dry-run',)
  37. )
  38. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  39. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  40. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  41. flexmock(module.environment).should_receive('make_environment')
  42. flexmock(module).should_receive('execute_command').with_args(
  43. ('borg', 'transfer', '--repo', 'repo', '--dry-run'),
  44. output_log_level=module.borgmatic.logger.ANSWER,
  45. output_file=None,
  46. borg_local_path='borg',
  47. extra_environment=None,
  48. )
  49. module.transfer_archives(
  50. dry_run=True,
  51. repository_path='repo',
  52. storage_config={},
  53. local_borg_version='2.3.4',
  54. transfer_arguments=flexmock(
  55. archive=None, progress=None, match_archives=None, source_repository=None
  56. ),
  57. global_arguments=flexmock(log_json=False),
  58. )
  59. def test_transfer_archives_with_log_info_calls_borg_with_info_flag():
  60. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  61. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  62. flexmock(module.flags).should_receive('make_flags').and_return(())
  63. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  64. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  65. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  66. flexmock(module.environment).should_receive('make_environment')
  67. flexmock(module).should_receive('execute_command').with_args(
  68. ('borg', 'transfer', '--info', '--repo', 'repo'),
  69. output_log_level=module.borgmatic.logger.ANSWER,
  70. output_file=None,
  71. borg_local_path='borg',
  72. extra_environment=None,
  73. )
  74. insert_logging_mock(logging.INFO)
  75. module.transfer_archives(
  76. dry_run=False,
  77. repository_path='repo',
  78. storage_config={},
  79. local_borg_version='2.3.4',
  80. transfer_arguments=flexmock(
  81. archive=None, progress=None, match_archives=None, source_repository=None
  82. ),
  83. global_arguments=flexmock(log_json=False),
  84. )
  85. def test_transfer_archives_with_log_debug_calls_borg_with_debug_flag():
  86. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  87. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  88. flexmock(module.flags).should_receive('make_flags').and_return(())
  89. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  90. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  91. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  92. flexmock(module.environment).should_receive('make_environment')
  93. flexmock(module).should_receive('execute_command').with_args(
  94. ('borg', 'transfer', '--debug', '--show-rc', '--repo', 'repo'),
  95. output_log_level=module.borgmatic.logger.ANSWER,
  96. output_file=None,
  97. borg_local_path='borg',
  98. extra_environment=None,
  99. )
  100. insert_logging_mock(logging.DEBUG)
  101. module.transfer_archives(
  102. dry_run=False,
  103. repository_path='repo',
  104. storage_config={},
  105. local_borg_version='2.3.4',
  106. transfer_arguments=flexmock(
  107. archive=None, progress=None, match_archives=None, source_repository=None
  108. ),
  109. global_arguments=flexmock(log_json=False),
  110. )
  111. def test_transfer_archives_with_archive_calls_borg_with_match_archives_flag():
  112. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  113. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  114. flexmock(module.flags).should_receive('make_flags').and_return(())
  115. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  116. 'archive', 'bar-{now}', '2.3.4' # noqa: FS003
  117. ).and_return(('--match-archives', 'archive'))
  118. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  119. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  120. flexmock(module.environment).should_receive('make_environment')
  121. flexmock(module).should_receive('execute_command').with_args(
  122. ('borg', 'transfer', '--match-archives', 'archive', '--repo', 'repo'),
  123. output_log_level=module.borgmatic.logger.ANSWER,
  124. output_file=None,
  125. borg_local_path='borg',
  126. extra_environment=None,
  127. )
  128. module.transfer_archives(
  129. dry_run=False,
  130. repository_path='repo',
  131. storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
  132. local_borg_version='2.3.4',
  133. transfer_arguments=flexmock(
  134. archive='archive', progress=None, match_archives=None, source_repository=None
  135. ),
  136. global_arguments=flexmock(log_json=False),
  137. )
  138. def test_transfer_archives_with_match_archives_calls_borg_with_match_archives_flag():
  139. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  140. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  141. flexmock(module.flags).should_receive('make_flags').and_return(())
  142. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  143. 'sh:foo*', 'bar-{now}', '2.3.4' # noqa: FS003
  144. ).and_return(('--match-archives', 'sh:foo*'))
  145. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  146. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  147. flexmock(module.environment).should_receive('make_environment')
  148. flexmock(module).should_receive('execute_command').with_args(
  149. ('borg', 'transfer', '--match-archives', 'sh:foo*', '--repo', 'repo'),
  150. output_log_level=module.borgmatic.logger.ANSWER,
  151. output_file=None,
  152. borg_local_path='borg',
  153. extra_environment=None,
  154. )
  155. module.transfer_archives(
  156. dry_run=False,
  157. repository_path='repo',
  158. storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
  159. local_borg_version='2.3.4',
  160. transfer_arguments=flexmock(
  161. archive=None, progress=None, match_archives='sh:foo*', source_repository=None
  162. ),
  163. global_arguments=flexmock(log_json=False),
  164. )
  165. def test_transfer_archives_with_archive_name_format_calls_borg_with_match_archives_flag():
  166. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  167. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  168. flexmock(module.flags).should_receive('make_flags').and_return(())
  169. flexmock(module.flags).should_receive('make_match_archives_flags').with_args(
  170. None, 'bar-{now}', '2.3.4' # noqa: FS003
  171. ).and_return(('--match-archives', 'sh:bar-*'))
  172. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  173. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  174. flexmock(module.environment).should_receive('make_environment')
  175. flexmock(module).should_receive('execute_command').with_args(
  176. ('borg', 'transfer', '--match-archives', 'sh:bar-*', '--repo', 'repo'),
  177. output_log_level=module.borgmatic.logger.ANSWER,
  178. output_file=None,
  179. borg_local_path='borg',
  180. extra_environment=None,
  181. )
  182. module.transfer_archives(
  183. dry_run=False,
  184. repository_path='repo',
  185. storage_config={'archive_name_format': 'bar-{now}'}, # noqa: FS003
  186. local_borg_version='2.3.4',
  187. transfer_arguments=flexmock(
  188. archive=None, progress=None, match_archives=None, source_repository=None
  189. ),
  190. global_arguments=flexmock(log_json=False),
  191. )
  192. def test_transfer_archives_with_local_path_calls_borg_via_local_path():
  193. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  194. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  195. flexmock(module.flags).should_receive('make_flags').and_return(())
  196. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  197. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  198. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  199. flexmock(module.environment).should_receive('make_environment')
  200. flexmock(module).should_receive('execute_command').with_args(
  201. ('borg2', 'transfer', '--repo', 'repo'),
  202. output_log_level=module.borgmatic.logger.ANSWER,
  203. output_file=None,
  204. borg_local_path='borg2',
  205. extra_environment=None,
  206. )
  207. module.transfer_archives(
  208. dry_run=False,
  209. repository_path='repo',
  210. storage_config={},
  211. local_borg_version='2.3.4',
  212. transfer_arguments=flexmock(
  213. archive=None, progress=None, match_archives=None, source_repository=None
  214. ),
  215. global_arguments=flexmock(log_json=False),
  216. local_path='borg2',
  217. )
  218. def test_transfer_archives_with_remote_path_calls_borg_with_remote_path_flags():
  219. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  220. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  221. flexmock(module.flags).should_receive('make_flags').and_return(())
  222. flexmock(module.flags).should_receive('make_flags').with_args(
  223. 'remote-path', 'borg2'
  224. ).and_return(('--remote-path', 'borg2'))
  225. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  226. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  227. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  228. flexmock(module.environment).should_receive('make_environment')
  229. flexmock(module).should_receive('execute_command').with_args(
  230. ('borg', 'transfer', '--remote-path', 'borg2', '--repo', 'repo'),
  231. output_log_level=module.borgmatic.logger.ANSWER,
  232. output_file=None,
  233. borg_local_path='borg',
  234. extra_environment=None,
  235. )
  236. module.transfer_archives(
  237. dry_run=False,
  238. repository_path='repo',
  239. storage_config={},
  240. local_borg_version='2.3.4',
  241. transfer_arguments=flexmock(
  242. archive=None, progress=None, match_archives=None, source_repository=None
  243. ),
  244. global_arguments=flexmock(log_json=False),
  245. remote_path='borg2',
  246. )
  247. def test_transfer_archives_with_log_json_calls_borg_with_log_json_flags():
  248. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  249. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  250. flexmock(module.flags).should_receive('make_flags').and_return(())
  251. flexmock(module.flags).should_receive('make_flags').with_args('log-json', True).and_return(
  252. ('--log-json',)
  253. )
  254. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  255. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  256. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  257. flexmock(module.environment).should_receive('make_environment')
  258. flexmock(module).should_receive('execute_command').with_args(
  259. ('borg', 'transfer', '--log-json', '--repo', 'repo'),
  260. output_log_level=module.borgmatic.logger.ANSWER,
  261. output_file=None,
  262. borg_local_path='borg',
  263. extra_environment=None,
  264. )
  265. module.transfer_archives(
  266. dry_run=False,
  267. repository_path='repo',
  268. storage_config={},
  269. local_borg_version='2.3.4',
  270. transfer_arguments=flexmock(
  271. archive=None, progress=None, match_archives=None, source_repository=None
  272. ),
  273. global_arguments=flexmock(log_json=True),
  274. )
  275. def test_transfer_archives_with_lock_wait_calls_borg_with_lock_wait_flags():
  276. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  277. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  278. flexmock(module.flags).should_receive('make_flags').and_return(())
  279. flexmock(module.flags).should_receive('make_flags').with_args('lock-wait', 5).and_return(
  280. ('--lock-wait', '5')
  281. )
  282. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  283. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  284. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  285. storage_config = {'lock_wait': 5}
  286. flexmock(module.environment).should_receive('make_environment')
  287. flexmock(module).should_receive('execute_command').with_args(
  288. ('borg', 'transfer', '--lock-wait', '5', '--repo', 'repo'),
  289. output_log_level=module.borgmatic.logger.ANSWER,
  290. output_file=None,
  291. borg_local_path='borg',
  292. extra_environment=None,
  293. )
  294. module.transfer_archives(
  295. dry_run=False,
  296. repository_path='repo',
  297. storage_config=storage_config,
  298. local_borg_version='2.3.4',
  299. transfer_arguments=flexmock(
  300. archive=None, progress=None, match_archives=None, source_repository=None
  301. ),
  302. global_arguments=flexmock(log_json=False),
  303. )
  304. def test_transfer_archives_with_progress_calls_borg_with_progress_flag():
  305. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  306. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  307. flexmock(module.flags).should_receive('make_flags').and_return(())
  308. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  309. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(('--progress',))
  310. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  311. flexmock(module.environment).should_receive('make_environment')
  312. flexmock(module).should_receive('execute_command').with_args(
  313. ('borg', 'transfer', '--progress', '--repo', 'repo'),
  314. output_log_level=module.borgmatic.logger.ANSWER,
  315. output_file=module.DO_NOT_CAPTURE,
  316. borg_local_path='borg',
  317. extra_environment=None,
  318. )
  319. module.transfer_archives(
  320. dry_run=False,
  321. repository_path='repo',
  322. storage_config={},
  323. local_borg_version='2.3.4',
  324. transfer_arguments=flexmock(
  325. archive=None, progress=True, match_archives=None, source_repository=None
  326. ),
  327. global_arguments=flexmock(log_json=False),
  328. )
  329. @pytest.mark.parametrize('argument_name', ('upgrader', 'sort_by', 'first', 'last'))
  330. def test_transfer_archives_passes_through_arguments_to_borg(argument_name):
  331. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  332. flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
  333. flag_name = f"--{argument_name.replace('_', ' ')}"
  334. flexmock(module.flags).should_receive('make_flags').and_return(())
  335. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  336. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
  337. (flag_name, 'value')
  338. )
  339. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  340. flexmock(module.environment).should_receive('make_environment')
  341. flexmock(module).should_receive('execute_command').with_args(
  342. ('borg', 'transfer', flag_name, 'value', '--repo', 'repo'),
  343. output_log_level=module.borgmatic.logger.ANSWER,
  344. output_file=None,
  345. borg_local_path='borg',
  346. extra_environment=None,
  347. )
  348. module.transfer_archives(
  349. dry_run=False,
  350. repository_path='repo',
  351. storage_config={},
  352. local_borg_version='2.3.4',
  353. transfer_arguments=flexmock(
  354. archive=None,
  355. progress=None,
  356. match_archives=None,
  357. source_repository=None,
  358. **{argument_name: 'value'},
  359. ),
  360. global_arguments=flexmock(log_json=False),
  361. )
  362. def test_transfer_archives_with_source_repository_calls_borg_with_other_repo_flags():
  363. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  364. flexmock(module.flags).should_receive('make_flags').and_return(())
  365. flexmock(module.flags).should_receive('make_flags').with_args('other-repo', 'other').and_return(
  366. ('--other-repo', 'other')
  367. )
  368. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  369. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(())
  370. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  371. flexmock(module.environment).should_receive('make_environment')
  372. flexmock(module).should_receive('execute_command').with_args(
  373. ('borg', 'transfer', '--repo', 'repo', '--other-repo', 'other'),
  374. output_log_level=module.borgmatic.logger.ANSWER,
  375. output_file=None,
  376. borg_local_path='borg',
  377. extra_environment=None,
  378. )
  379. module.transfer_archives(
  380. dry_run=False,
  381. repository_path='repo',
  382. storage_config={},
  383. local_borg_version='2.3.4',
  384. transfer_arguments=flexmock(
  385. archive=None, progress=None, match_archives=None, source_repository='other'
  386. ),
  387. global_arguments=flexmock(log_json=False),
  388. )
  389. def test_transfer_archives_with_date_based_matching_calls_borg_with_date_based_flags():
  390. flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels')
  391. flexmock(module.flags).should_receive('make_flags').and_return(())
  392. flexmock(module.flags).should_receive('make_match_archives_flags').and_return(())
  393. flexmock(module.flags).should_receive('make_flags_from_arguments').and_return(
  394. ('--newer', '1d', '--newest', '1y', '--older', '1m', '--oldest', '1w')
  395. )
  396. flexmock(module.flags).should_receive('make_repository_flags').and_return(('--repo', 'repo'))
  397. flexmock(module.environment).should_receive('make_environment')
  398. flexmock(module).should_receive('execute_command').with_args(
  399. (
  400. 'borg',
  401. 'transfer',
  402. '--newer',
  403. '1d',
  404. '--newest',
  405. '1y',
  406. '--older',
  407. '1m',
  408. '--oldest',
  409. '1w',
  410. '--repo',
  411. 'repo',
  412. ),
  413. output_log_level=module.borgmatic.logger.ANSWER,
  414. output_file=None,
  415. borg_local_path='borg',
  416. extra_environment=None,
  417. )
  418. module.transfer_archives(
  419. dry_run=False,
  420. repository_path='repo',
  421. storage_config={},
  422. local_borg_version='2.3.4',
  423. global_arguments=flexmock(log_json=False),
  424. transfer_arguments=flexmock(
  425. archive=None,
  426. progress=None,
  427. source_repository='other',
  428. newer='1d',
  429. newest='1y',
  430. older='1m',
  431. oldest='1w',
  432. ),
  433. )