test_extract.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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).should_receive('execute_command').with_args(
  8. command, working_directory=working_directory
  9. ).once()
  10. def insert_execute_command_output_mock(command, result):
  11. flexmock(module).should_receive('execute_command').with_args(
  12. command, output_log_level=None, borg_local_path=command[0]
  13. ).and_return(result).once()
  14. def test_extract_last_archive_dry_run_calls_borg_with_last_archive():
  15. insert_execute_command_output_mock(
  16. ('borg', 'list', '--short', 'repo'), result='archive1\narchive2\n'
  17. )
  18. insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive2'))
  19. flexmock(module.feature).should_receive('available').and_return(True)
  20. module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
  21. def test_extract_last_archive_dry_run_without_any_archives_should_not_raise():
  22. insert_execute_command_output_mock(('borg', 'list', '--short', 'repo'), result='\n')
  23. flexmock(module.feature).should_receive('available').and_return(True)
  24. module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
  25. def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_parameter():
  26. insert_execute_command_output_mock(
  27. ('borg', 'list', '--short', '--info', 'repo'), result='archive1\narchive2\n'
  28. )
  29. insert_execute_command_mock(('borg', 'extract', '--dry-run', '--info', 'repo::archive2'))
  30. insert_logging_mock(logging.INFO)
  31. flexmock(module.feature).should_receive('available').and_return(True)
  32. module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
  33. def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter():
  34. insert_execute_command_output_mock(
  35. ('borg', 'list', '--short', '--debug', '--show-rc', 'repo'), result='archive1\narchive2\n'
  36. )
  37. insert_execute_command_mock(
  38. ('borg', 'extract', '--dry-run', '--debug', '--show-rc', '--list', 'repo::archive2')
  39. )
  40. insert_logging_mock(logging.DEBUG)
  41. flexmock(module.feature).should_receive('available').and_return(True)
  42. module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
  43. def test_extract_last_archive_dry_run_calls_borg_via_local_path():
  44. insert_execute_command_output_mock(
  45. ('borg1', 'list', '--short', 'repo'), result='archive1\narchive2\n'
  46. )
  47. insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive2'))
  48. flexmock(module.feature).should_receive('available').and_return(True)
  49. module.extract_last_archive_dry_run(repository='repo', lock_wait=None, local_path='borg1')
  50. def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters():
  51. insert_execute_command_output_mock(
  52. ('borg', 'list', '--short', '--remote-path', 'borg1', 'repo'), result='archive1\narchive2\n'
  53. )
  54. insert_execute_command_mock(
  55. ('borg', 'extract', '--dry-run', '--remote-path', 'borg1', 'repo::archive2')
  56. )
  57. flexmock(module.feature).should_receive('available').and_return(True)
  58. module.extract_last_archive_dry_run(repository='repo', lock_wait=None, remote_path='borg1')
  59. def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters():
  60. insert_execute_command_output_mock(
  61. ('borg', 'list', '--short', '--lock-wait', '5', 'repo'), result='archive1\narchive2\n'
  62. )
  63. insert_execute_command_mock(
  64. ('borg', 'extract', '--dry-run', '--lock-wait', '5', 'repo::archive2')
  65. )
  66. flexmock(module.feature).should_receive('available').and_return(True)
  67. module.extract_last_archive_dry_run(repository='repo', lock_wait=5)
  68. def test_extract_archive_calls_borg_with_path_parameters():
  69. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  70. insert_execute_command_mock(('borg', 'extract', 'repo::archive', 'path1', 'path2'))
  71. flexmock(module.feature).should_receive('available').and_return(True)
  72. module.extract_archive(
  73. dry_run=False,
  74. repository='repo',
  75. archive='archive',
  76. paths=['path1', 'path2'],
  77. location_config={},
  78. storage_config={},
  79. local_borg_version='1.2.3',
  80. )
  81. def test_extract_archive_calls_borg_with_remote_path_parameters():
  82. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  83. insert_execute_command_mock(('borg', 'extract', '--remote-path', 'borg1', 'repo::archive'))
  84. flexmock(module.feature).should_receive('available').and_return(True)
  85. module.extract_archive(
  86. dry_run=False,
  87. repository='repo',
  88. archive='archive',
  89. paths=None,
  90. location_config={},
  91. storage_config={},
  92. local_borg_version='1.2.3',
  93. remote_path='borg1',
  94. )
  95. @pytest.mark.parametrize(
  96. 'feature_available,option_flag', ((True, '--numeric-ids'), (False, '--numeric-owner'),),
  97. )
  98. def test_extract_archive_calls_borg_with_numeric_ids_parameter(feature_available, option_flag):
  99. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  100. insert_execute_command_mock(('borg', 'extract', option_flag, 'repo::archive'))
  101. flexmock(module.feature).should_receive('available').and_return(feature_available)
  102. module.extract_archive(
  103. dry_run=False,
  104. repository='repo',
  105. archive='archive',
  106. paths=None,
  107. location_config={'numeric_owner': True},
  108. storage_config={},
  109. local_borg_version='1.2.3',
  110. )
  111. def test_extract_archive_calls_borg_with_umask_parameters():
  112. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  113. insert_execute_command_mock(('borg', 'extract', '--umask', '0770', 'repo::archive'))
  114. flexmock(module.feature).should_receive('available').and_return(True)
  115. module.extract_archive(
  116. dry_run=False,
  117. repository='repo',
  118. archive='archive',
  119. paths=None,
  120. location_config={},
  121. storage_config={'umask': '0770'},
  122. local_borg_version='1.2.3',
  123. )
  124. def test_extract_archive_calls_borg_with_lock_wait_parameters():
  125. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  126. insert_execute_command_mock(('borg', 'extract', '--lock-wait', '5', 'repo::archive'))
  127. flexmock(module.feature).should_receive('available').and_return(True)
  128. module.extract_archive(
  129. dry_run=False,
  130. repository='repo',
  131. archive='archive',
  132. paths=None,
  133. location_config={},
  134. storage_config={'lock_wait': '5'},
  135. local_borg_version='1.2.3',
  136. )
  137. def test_extract_archive_with_log_info_calls_borg_with_info_parameter():
  138. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  139. insert_execute_command_mock(('borg', 'extract', '--info', 'repo::archive'))
  140. insert_logging_mock(logging.INFO)
  141. flexmock(module.feature).should_receive('available').and_return(True)
  142. module.extract_archive(
  143. dry_run=False,
  144. repository='repo',
  145. archive='archive',
  146. paths=None,
  147. location_config={},
  148. storage_config={},
  149. local_borg_version='1.2.3',
  150. )
  151. def test_extract_archive_with_log_debug_calls_borg_with_debug_parameters():
  152. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  153. insert_execute_command_mock(
  154. ('borg', 'extract', '--debug', '--list', '--show-rc', 'repo::archive')
  155. )
  156. insert_logging_mock(logging.DEBUG)
  157. flexmock(module.feature).should_receive('available').and_return(True)
  158. module.extract_archive(
  159. dry_run=False,
  160. repository='repo',
  161. archive='archive',
  162. paths=None,
  163. location_config={},
  164. storage_config={},
  165. local_borg_version='1.2.3',
  166. )
  167. def test_extract_archive_calls_borg_with_dry_run_parameter():
  168. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  169. insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive'))
  170. flexmock(module.feature).should_receive('available').and_return(True)
  171. module.extract_archive(
  172. dry_run=True,
  173. repository='repo',
  174. archive='archive',
  175. paths=None,
  176. location_config={},
  177. storage_config={},
  178. local_borg_version='1.2.3',
  179. )
  180. def test_extract_archive_calls_borg_with_destination_path():
  181. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  182. insert_execute_command_mock(('borg', 'extract', 'repo::archive'), working_directory='/dest')
  183. flexmock(module.feature).should_receive('available').and_return(True)
  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. destination_path='/dest',
  193. )
  194. def test_extract_archive_calls_borg_with_strip_components():
  195. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  196. insert_execute_command_mock(('borg', 'extract', '--strip-components', '5', 'repo::archive'))
  197. flexmock(module.feature).should_receive('available').and_return(True)
  198. module.extract_archive(
  199. dry_run=False,
  200. repository='repo',
  201. archive='archive',
  202. paths=None,
  203. location_config={},
  204. storage_config={},
  205. local_borg_version='1.2.3',
  206. strip_components=5,
  207. )
  208. def test_extract_archive_calls_borg_with_progress_parameter():
  209. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  210. flexmock(module).should_receive('execute_command').with_args(
  211. ('borg', 'extract', '--progress', 'repo::archive'),
  212. output_file=module.DO_NOT_CAPTURE,
  213. working_directory=None,
  214. ).once()
  215. flexmock(module.feature).should_receive('available').and_return(True)
  216. module.extract_archive(
  217. dry_run=False,
  218. repository='repo',
  219. archive='archive',
  220. paths=None,
  221. location_config={},
  222. storage_config={},
  223. local_borg_version='1.2.3',
  224. progress=True,
  225. )
  226. def test_extract_archive_with_progress_and_extract_to_stdout_raises():
  227. flexmock(module).should_receive('execute_command').never()
  228. with pytest.raises(ValueError):
  229. module.extract_archive(
  230. dry_run=False,
  231. repository='repo',
  232. archive='archive',
  233. paths=None,
  234. location_config={},
  235. storage_config={},
  236. local_borg_version='1.2.3',
  237. progress=True,
  238. extract_to_stdout=True,
  239. )
  240. def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process():
  241. flexmock(module.os.path).should_receive('abspath').and_return('repo')
  242. process = flexmock()
  243. flexmock(module).should_receive('execute_command').with_args(
  244. ('borg', 'extract', '--stdout', 'repo::archive'),
  245. output_file=module.subprocess.PIPE,
  246. working_directory=None,
  247. run_to_completion=False,
  248. ).and_return(process).once()
  249. flexmock(module.feature).should_receive('available').and_return(True)
  250. assert (
  251. module.extract_archive(
  252. dry_run=False,
  253. repository='repo',
  254. archive='archive',
  255. paths=None,
  256. location_config={},
  257. storage_config={},
  258. local_borg_version='1.2.3',
  259. extract_to_stdout=True,
  260. )
  261. == process
  262. )
  263. def test_extract_archive_skips_abspath_for_remote_repository():
  264. flexmock(module.os.path).should_receive('abspath').never()
  265. flexmock(module).should_receive('execute_command').with_args(
  266. ('borg', 'extract', 'server:repo::archive'), working_directory=None
  267. ).once()
  268. flexmock(module.feature).should_receive('available').and_return(True)
  269. module.extract_archive(
  270. dry_run=False,
  271. repository='server:repo',
  272. archive='archive',
  273. paths=None,
  274. location_config={},
  275. storage_config={},
  276. local_borg_version='1.2.3',
  277. )