test_extract.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. import logging
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic.borg import extract as module
  5. from ..test_verbosity import insert_logging_mock
  6. def insert_execute_command_mock(command, working_directory=None):
  7. flexmock(module.environment).should_receive('make_environment')
  8. flexmock(module).should_receive('execute_command').with_args(
  9. command, working_directory=working_directory, extra_environment=None,
  10. ).once()
  11. def insert_execute_command_output_mock(command, result):
  12. flexmock(module.environment).should_receive('make_environment')
  13. flexmock(module).should_receive('execute_command').with_args(
  14. command, output_log_level=None, borg_local_path=command[0], extra_environment=None,
  15. ).and_return(result).once()
  16. def test_extract_last_archive_dry_run_calls_borg_with_last_archive():
  17. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  18. insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive'))
  19. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  20. ('repo::archive',)
  21. )
  22. module.extract_last_archive_dry_run(
  23. storage_config={}, local_borg_version='1.2.3', repository='repo', lock_wait=None
  24. )
  25. def test_extract_last_archive_dry_run_without_any_archives_should_not_raise():
  26. flexmock(module.rlist).should_receive('resolve_archive_name').and_raise(ValueError)
  27. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(('repo',))
  28. module.extract_last_archive_dry_run(
  29. storage_config={}, local_borg_version='1.2.3', repository='repo', lock_wait=None
  30. )
  31. def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_parameter():
  32. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  33. insert_execute_command_mock(('borg', 'extract', '--dry-run', '--info', 'repo::archive'))
  34. insert_logging_mock(logging.INFO)
  35. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  36. ('repo::archive',)
  37. )
  38. module.extract_last_archive_dry_run(
  39. storage_config={}, local_borg_version='1.2.3', repository='repo', lock_wait=None
  40. )
  41. def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter():
  42. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  43. insert_execute_command_mock(
  44. ('borg', 'extract', '--dry-run', '--debug', '--show-rc', '--list', 'repo::archive')
  45. )
  46. insert_logging_mock(logging.DEBUG)
  47. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  48. ('repo::archive',)
  49. )
  50. module.extract_last_archive_dry_run(
  51. storage_config={}, local_borg_version='1.2.3', repository='repo', lock_wait=None
  52. )
  53. def test_extract_last_archive_dry_run_calls_borg_via_local_path():
  54. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  55. insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive'))
  56. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  57. ('repo::archive',)
  58. )
  59. module.extract_last_archive_dry_run(
  60. storage_config={},
  61. local_borg_version='1.2.3',
  62. repository='repo',
  63. lock_wait=None,
  64. local_path='borg1',
  65. )
  66. def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters():
  67. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  68. insert_execute_command_mock(
  69. ('borg', 'extract', '--dry-run', '--remote-path', 'borg1', 'repo::archive')
  70. )
  71. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  72. ('repo::archive',)
  73. )
  74. module.extract_last_archive_dry_run(
  75. storage_config={},
  76. local_borg_version='1.2.3',
  77. repository='repo',
  78. lock_wait=None,
  79. remote_path='borg1',
  80. )
  81. def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters():
  82. flexmock(module.rlist).should_receive('resolve_archive_name').and_return('archive')
  83. insert_execute_command_mock(
  84. ('borg', 'extract', '--dry-run', '--lock-wait', '5', 'repo::archive')
  85. )
  86. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  87. ('repo::archive',)
  88. )
  89. module.extract_last_archive_dry_run(
  90. storage_config={}, local_borg_version='1.2.3', repository='repo', lock_wait=5
  91. )
  92. def test_extract_archive_calls_borg_with_path_parameters():
  93. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  94. insert_execute_command_mock(('borg', 'extract', 'repo::archive', 'path1', 'path2'))
  95. flexmock(module.feature).should_receive('available').and_return(True)
  96. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  97. ('repo::archive',)
  98. )
  99. module.extract_archive(
  100. dry_run=False,
  101. repository='repo',
  102. archive='archive',
  103. paths=['path1', 'path2'],
  104. location_config={},
  105. storage_config={},
  106. local_borg_version='1.2.3',
  107. )
  108. def test_extract_archive_calls_borg_with_remote_path_parameters():
  109. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  110. insert_execute_command_mock(('borg', 'extract', '--remote-path', 'borg1', 'repo::archive'))
  111. flexmock(module.feature).should_receive('available').and_return(True)
  112. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  113. ('repo::archive',)
  114. )
  115. module.extract_archive(
  116. dry_run=False,
  117. repository='repo',
  118. archive='archive',
  119. paths=None,
  120. location_config={},
  121. storage_config={},
  122. local_borg_version='1.2.3',
  123. remote_path='borg1',
  124. )
  125. @pytest.mark.parametrize(
  126. 'feature_available,option_flag', ((True, '--numeric-ids'), (False, '--numeric-owner'),),
  127. )
  128. def test_extract_archive_calls_borg_with_numeric_ids_parameter(feature_available, option_flag):
  129. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  130. insert_execute_command_mock(('borg', 'extract', option_flag, 'repo::archive'))
  131. flexmock(module.feature).should_receive('available').and_return(feature_available)
  132. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  133. ('repo::archive',)
  134. )
  135. module.extract_archive(
  136. dry_run=False,
  137. repository='repo',
  138. archive='archive',
  139. paths=None,
  140. location_config={'numeric_ids': True},
  141. storage_config={},
  142. local_borg_version='1.2.3',
  143. )
  144. def test_extract_archive_calls_borg_with_umask_parameters():
  145. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  146. insert_execute_command_mock(('borg', 'extract', '--umask', '0770', 'repo::archive'))
  147. flexmock(module.feature).should_receive('available').and_return(True)
  148. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  149. ('repo::archive',)
  150. )
  151. module.extract_archive(
  152. dry_run=False,
  153. repository='repo',
  154. archive='archive',
  155. paths=None,
  156. location_config={},
  157. storage_config={'umask': '0770'},
  158. local_borg_version='1.2.3',
  159. )
  160. def test_extract_archive_calls_borg_with_lock_wait_parameters():
  161. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  162. insert_execute_command_mock(('borg', 'extract', '--lock-wait', '5', 'repo::archive'))
  163. flexmock(module.feature).should_receive('available').and_return(True)
  164. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  165. ('repo::archive',)
  166. )
  167. module.extract_archive(
  168. dry_run=False,
  169. repository='repo',
  170. archive='archive',
  171. paths=None,
  172. location_config={},
  173. storage_config={'lock_wait': '5'},
  174. local_borg_version='1.2.3',
  175. )
  176. def test_extract_archive_with_log_info_calls_borg_with_info_parameter():
  177. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  178. insert_execute_command_mock(('borg', 'extract', '--info', 'repo::archive'))
  179. insert_logging_mock(logging.INFO)
  180. flexmock(module.feature).should_receive('available').and_return(True)
  181. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  182. ('repo::archive',)
  183. )
  184. module.extract_archive(
  185. dry_run=False,
  186. repository='repo',
  187. archive='archive',
  188. paths=None,
  189. location_config={},
  190. storage_config={},
  191. local_borg_version='1.2.3',
  192. )
  193. def test_extract_archive_with_log_debug_calls_borg_with_debug_parameters():
  194. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  195. insert_execute_command_mock(
  196. ('borg', 'extract', '--debug', '--list', '--show-rc', 'repo::archive')
  197. )
  198. insert_logging_mock(logging.DEBUG)
  199. flexmock(module.feature).should_receive('available').and_return(True)
  200. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  201. ('repo::archive',)
  202. )
  203. module.extract_archive(
  204. dry_run=False,
  205. repository='repo',
  206. archive='archive',
  207. paths=None,
  208. location_config={},
  209. storage_config={},
  210. local_borg_version='1.2.3',
  211. )
  212. def test_extract_archive_calls_borg_with_dry_run_parameter():
  213. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  214. insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive'))
  215. flexmock(module.feature).should_receive('available').and_return(True)
  216. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  217. ('repo::archive',)
  218. )
  219. module.extract_archive(
  220. dry_run=True,
  221. repository='repo',
  222. archive='archive',
  223. paths=None,
  224. location_config={},
  225. storage_config={},
  226. local_borg_version='1.2.3',
  227. )
  228. def test_extract_archive_calls_borg_with_destination_path():
  229. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  230. insert_execute_command_mock(('borg', 'extract', 'repo::archive'), working_directory='/dest')
  231. flexmock(module.feature).should_receive('available').and_return(True)
  232. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  233. ('repo::archive',)
  234. )
  235. module.extract_archive(
  236. dry_run=False,
  237. repository='repo',
  238. archive='archive',
  239. paths=None,
  240. location_config={},
  241. storage_config={},
  242. local_borg_version='1.2.3',
  243. destination_path='/dest',
  244. )
  245. def test_extract_archive_calls_borg_with_strip_components():
  246. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  247. insert_execute_command_mock(('borg', 'extract', '--strip-components', '5', 'repo::archive'))
  248. flexmock(module.feature).should_receive('available').and_return(True)
  249. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  250. ('repo::archive',)
  251. )
  252. module.extract_archive(
  253. dry_run=False,
  254. repository='repo',
  255. archive='archive',
  256. paths=None,
  257. location_config={},
  258. storage_config={},
  259. local_borg_version='1.2.3',
  260. strip_components=5,
  261. )
  262. def test_extract_archive_calls_borg_with_progress_parameter():
  263. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  264. flexmock(module.environment).should_receive('make_environment')
  265. flexmock(module).should_receive('execute_command').with_args(
  266. ('borg', 'extract', '--progress', 'repo::archive'),
  267. output_file=module.DO_NOT_CAPTURE,
  268. working_directory=None,
  269. extra_environment=None,
  270. ).once()
  271. flexmock(module.feature).should_receive('available').and_return(True)
  272. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  273. ('repo::archive',)
  274. )
  275. module.extract_archive(
  276. dry_run=False,
  277. repository='repo',
  278. archive='archive',
  279. paths=None,
  280. location_config={},
  281. storage_config={},
  282. local_borg_version='1.2.3',
  283. progress=True,
  284. )
  285. def test_extract_archive_with_progress_and_extract_to_stdout_raises():
  286. flexmock(module).should_receive('execute_command').never()
  287. with pytest.raises(ValueError):
  288. module.extract_archive(
  289. dry_run=False,
  290. repository='repo',
  291. archive='archive',
  292. paths=None,
  293. location_config={},
  294. storage_config={},
  295. local_borg_version='1.2.3',
  296. progress=True,
  297. extract_to_stdout=True,
  298. )
  299. def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process():
  300. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  301. process = flexmock()
  302. flexmock(module.environment).should_receive('make_environment')
  303. flexmock(module).should_receive('execute_command').with_args(
  304. ('borg', 'extract', '--stdout', 'repo::archive'),
  305. output_file=module.subprocess.PIPE,
  306. working_directory=None,
  307. run_to_completion=False,
  308. extra_environment=None,
  309. ).and_return(process).once()
  310. flexmock(module.feature).should_receive('available').and_return(True)
  311. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  312. ('repo::archive',)
  313. )
  314. assert (
  315. module.extract_archive(
  316. dry_run=False,
  317. repository='repo',
  318. archive='archive',
  319. paths=None,
  320. location_config={},
  321. storage_config={},
  322. local_borg_version='1.2.3',
  323. extract_to_stdout=True,
  324. )
  325. == process
  326. )
  327. def test_extract_archive_skips_abspath_for_remote_repository():
  328. flexmock(module.os.path).should_receive('abspath').never()
  329. flexmock(module.environment).should_receive('make_environment')
  330. flexmock(module).should_receive('execute_command').with_args(
  331. ('borg', 'extract', 'server:repo::archive'), working_directory=None, extra_environment=None,
  332. ).once()
  333. flexmock(module.feature).should_receive('available').and_return(True)
  334. flexmock(module.flags).should_receive('make_repository_archive_flags').and_return(
  335. ('server:repo::archive',)
  336. )
  337. module.extract_archive(
  338. dry_run=False,
  339. repository='server:repo',
  340. archive='archive',
  341. paths=None,
  342. location_config={},
  343. storage_config={},
  344. local_borg_version='1.2.3',
  345. )