test_bootstrap.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. import pytest
  2. from flexmock import flexmock
  3. from borgmatic.actions.config import bootstrap as module
  4. def test_make_bootstrap_config_uses_ssh_command_argument():
  5. ssh_command = flexmock()
  6. config = module.make_bootstrap_config(flexmock(ssh_command=ssh_command))
  7. assert config['ssh_command'] == ssh_command
  8. assert config['relocated_repo_access_is_ok']
  9. def test_get_config_paths_returns_list_of_config_paths():
  10. flexmock(module.borgmatic.config.paths).should_receive(
  11. 'get_borgmatic_source_directory'
  12. ).and_return('/source')
  13. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  14. bootstrap_arguments = flexmock(
  15. repository='repo',
  16. archive='archive',
  17. ssh_command=None,
  18. local_path='borg7',
  19. remote_path='borg8',
  20. borgmatic_source_directory=None,
  21. user_runtime_directory=None,
  22. )
  23. global_arguments = flexmock(
  24. dry_run=False,
  25. )
  26. local_borg_version = flexmock()
  27. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  28. flexmock()
  29. )
  30. extract_process = flexmock(
  31. stdout=flexmock(
  32. read=lambda: '{"config_paths": ["/borgmatic/config.yaml"]}',
  33. ),
  34. )
  35. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  36. extract_process
  37. )
  38. assert module.get_config_paths(
  39. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  40. ) == ['/borgmatic/config.yaml']
  41. def test_get_config_paths_probes_for_manifest():
  42. flexmock(module.borgmatic.config.paths).should_receive(
  43. 'get_borgmatic_source_directory'
  44. ).and_return('/source')
  45. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  46. bootstrap_arguments = flexmock(
  47. repository='repo',
  48. archive='archive',
  49. ssh_command=None,
  50. local_path='borg7',
  51. remote_path='borg8',
  52. borgmatic_source_directory=None,
  53. user_runtime_directory=None,
  54. )
  55. global_arguments = flexmock(
  56. dry_run=False,
  57. )
  58. local_borg_version = flexmock()
  59. borgmatic_runtime_directory = flexmock()
  60. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  61. borgmatic_runtime_directory,
  62. )
  63. flexmock(module.os.path).should_receive('join').with_args(
  64. 'borgmatic', 'bootstrap', 'manifest.json'
  65. ).and_return(flexmock()).once()
  66. flexmock(module.os.path).should_receive('join').with_args(
  67. borgmatic_runtime_directory, 'bootstrap', 'manifest.json'
  68. ).and_return(flexmock()).once()
  69. flexmock(module.os.path).should_receive('join').with_args(
  70. '/source', 'bootstrap', 'manifest.json'
  71. ).and_return(flexmock()).once()
  72. manifest_missing_extract_process = flexmock(
  73. stdout=flexmock(read=lambda: None),
  74. )
  75. manifest_found_extract_process = flexmock(
  76. stdout=flexmock(
  77. read=lambda: '{"config_paths": ["/borgmatic/config.yaml"]}',
  78. ),
  79. )
  80. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  81. manifest_missing_extract_process
  82. ).and_return(manifest_missing_extract_process).and_return(manifest_found_extract_process)
  83. assert module.get_config_paths(
  84. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  85. ) == ['/borgmatic/config.yaml']
  86. def test_get_config_paths_translates_ssh_command_argument_to_config():
  87. flexmock(module.borgmatic.config.paths).should_receive(
  88. 'get_borgmatic_source_directory'
  89. ).and_return('/source')
  90. config = flexmock()
  91. flexmock(module).should_receive('make_bootstrap_config').and_return(config)
  92. bootstrap_arguments = flexmock(
  93. repository='repo',
  94. archive='archive',
  95. ssh_command='ssh -i key',
  96. local_path='borg7',
  97. remote_path='borg8',
  98. borgmatic_source_directory=None,
  99. user_runtime_directory=None,
  100. )
  101. global_arguments = flexmock(
  102. dry_run=False,
  103. )
  104. local_borg_version = flexmock()
  105. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  106. flexmock()
  107. )
  108. extract_process = flexmock(
  109. stdout=flexmock(
  110. read=lambda: '{"config_paths": ["/borgmatic/config.yaml"]}',
  111. ),
  112. )
  113. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').with_args(
  114. False,
  115. 'repo',
  116. 'archive',
  117. object,
  118. config,
  119. object,
  120. object,
  121. extract_to_stdout=True,
  122. local_path='borg7',
  123. remote_path='borg8',
  124. ).and_return(extract_process)
  125. assert module.get_config_paths(
  126. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  127. ) == ['/borgmatic/config.yaml']
  128. def test_get_config_paths_with_missing_manifest_raises_value_error():
  129. flexmock(module.borgmatic.config.paths).should_receive(
  130. 'get_borgmatic_source_directory'
  131. ).and_return('/source')
  132. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  133. bootstrap_arguments = flexmock(
  134. repository='repo',
  135. archive='archive',
  136. ssh_command=None,
  137. local_path='borg7',
  138. remote_path='borg7',
  139. borgmatic_source_directory=None,
  140. user_runtime_directory=None,
  141. )
  142. global_arguments = flexmock(
  143. dry_run=False,
  144. )
  145. local_borg_version = flexmock()
  146. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  147. flexmock()
  148. )
  149. flexmock(module.os.path).should_receive('join').and_return(flexmock())
  150. extract_process = flexmock(stdout=flexmock(read=lambda: ''))
  151. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  152. extract_process
  153. )
  154. with pytest.raises(ValueError):
  155. module.get_config_paths(
  156. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  157. )
  158. def test_get_config_paths_with_broken_json_raises_value_error():
  159. flexmock(module.borgmatic.config.paths).should_receive(
  160. 'get_borgmatic_source_directory'
  161. ).and_return('/source')
  162. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  163. bootstrap_arguments = flexmock(
  164. repository='repo',
  165. archive='archive',
  166. ssh_command=None,
  167. local_path='borg7',
  168. remote_path='borg7',
  169. borgmatic_source_directory=None,
  170. user_runtime_directory=None,
  171. )
  172. global_arguments = flexmock(
  173. dry_run=False,
  174. )
  175. local_borg_version = flexmock()
  176. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  177. flexmock()
  178. )
  179. extract_process = flexmock(
  180. stdout=flexmock(read=lambda: '{"config_paths": ["/oops'),
  181. )
  182. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  183. extract_process
  184. )
  185. with pytest.raises(ValueError):
  186. module.get_config_paths(
  187. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  188. )
  189. def test_get_config_paths_with_json_missing_key_raises_value_error():
  190. flexmock(module.borgmatic.config.paths).should_receive(
  191. 'get_borgmatic_source_directory'
  192. ).and_return('/source')
  193. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  194. bootstrap_arguments = flexmock(
  195. repository='repo',
  196. archive='archive',
  197. ssh_command=None,
  198. local_path='borg7',
  199. remote_path='borg7',
  200. borgmatic_source_directory=None,
  201. user_runtime_directory=None,
  202. )
  203. global_arguments = flexmock(
  204. dry_run=False,
  205. )
  206. local_borg_version = flexmock()
  207. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  208. flexmock()
  209. )
  210. extract_process = flexmock(
  211. stdout=flexmock(read=lambda: '{}'),
  212. )
  213. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  214. extract_process
  215. )
  216. with pytest.raises(ValueError):
  217. module.get_config_paths(
  218. 'archive', bootstrap_arguments, global_arguments, local_borg_version
  219. )
  220. def test_run_bootstrap_does_not_raise():
  221. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  222. flexmock(module).should_receive('get_config_paths').and_return(['/borgmatic/config.yaml'])
  223. bootstrap_arguments = flexmock(
  224. repository='repo',
  225. archive='archive',
  226. destination='dest',
  227. strip_components=1,
  228. progress=False,
  229. user_runtime_directory='/borgmatic',
  230. ssh_command=None,
  231. local_path='borg7',
  232. remote_path='borg8',
  233. )
  234. global_arguments = flexmock(
  235. dry_run=False,
  236. )
  237. local_borg_version = flexmock()
  238. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  239. flexmock()
  240. )
  241. extract_process = flexmock(
  242. stdout=flexmock(
  243. read=lambda: '{"config_paths": ["borgmatic/config.yaml"]}',
  244. ),
  245. )
  246. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  247. extract_process
  248. ).once()
  249. flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
  250. 'archive'
  251. )
  252. module.run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version)
  253. def test_run_bootstrap_translates_ssh_command_argument_to_config():
  254. config = flexmock()
  255. flexmock(module).should_receive('make_bootstrap_config').and_return(config)
  256. flexmock(module).should_receive('get_config_paths').and_return(['/borgmatic/config.yaml'])
  257. bootstrap_arguments = flexmock(
  258. repository='repo',
  259. archive='archive',
  260. destination='dest',
  261. strip_components=1,
  262. progress=False,
  263. user_runtime_directory='/borgmatic',
  264. ssh_command='ssh -i key',
  265. local_path='borg7',
  266. remote_path='borg8',
  267. )
  268. global_arguments = flexmock(
  269. dry_run=False,
  270. )
  271. local_borg_version = flexmock()
  272. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  273. flexmock()
  274. )
  275. extract_process = flexmock(
  276. stdout=flexmock(
  277. read=lambda: '{"config_paths": ["borgmatic/config.yaml"]}',
  278. ),
  279. )
  280. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').with_args(
  281. False,
  282. 'repo',
  283. 'archive',
  284. object,
  285. config,
  286. object,
  287. object,
  288. extract_to_stdout=False,
  289. destination_path='dest',
  290. strip_components=1,
  291. progress=False,
  292. local_path='borg7',
  293. remote_path='borg8',
  294. ).and_return(extract_process).once()
  295. flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').with_args(
  296. 'repo',
  297. 'archive',
  298. config,
  299. object,
  300. object,
  301. local_path='borg7',
  302. remote_path='borg8',
  303. ).and_return('archive')
  304. module.run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version)