test_bootstrap.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. import pytest
  2. from flexmock import flexmock
  3. from borgmatic.actions.config import bootstrap as module
  4. def test_make_bootstrap_config_uses_bootstrap_arguments():
  5. config = module.make_bootstrap_config(
  6. flexmock(
  7. borgmatic_source_directory='/source',
  8. local_path='borg1',
  9. remote_path='borg2',
  10. ssh_command='ssh',
  11. user_runtime_directory='/run',
  12. )
  13. )
  14. assert config['borgmatic_source_directory'] == '/source'
  15. assert config['local_path'] == 'borg1'
  16. assert config['remote_path'] == 'borg2'
  17. assert config['relocated_repo_access_is_ok']
  18. assert config['ssh_command'] == 'ssh'
  19. assert config['user_runtime_directory'] == '/run'
  20. def test_load_config_paths_from_archive_returns_list_of_config_paths():
  21. flexmock(module.borgmatic.config.paths).should_receive(
  22. 'make_runtime_directory_glob',
  23. ).replace_with(lambda path: path)
  24. flexmock(module.borgmatic.config.paths).should_receive(
  25. 'get_borgmatic_source_directory',
  26. ).and_return('/source')
  27. extract_process = flexmock(
  28. stdout=flexmock(
  29. read=lambda: '{"config_paths": ["/borgmatic/config.yaml"]}',
  30. ),
  31. )
  32. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  33. extract_process,
  34. )
  35. assert module.load_config_paths_from_archive(
  36. 'repo',
  37. 'archive',
  38. config={},
  39. local_borg_version=flexmock(),
  40. global_arguments=flexmock(dry_run=False),
  41. borgmatic_runtime_directory='/run',
  42. ) == ['/borgmatic/config.yaml']
  43. def test_load_config_paths_from_archive_probes_for_manifest():
  44. flexmock(module.borgmatic.config.paths).should_receive(
  45. 'make_runtime_directory_glob',
  46. ).replace_with(lambda path: path)
  47. flexmock(module.borgmatic.config.paths).should_receive(
  48. 'get_borgmatic_source_directory',
  49. ).and_return('/source')
  50. flexmock(module.os.path).should_call('join').with_args(
  51. 'borgmatic',
  52. 'bootstrap',
  53. 'manifest.json',
  54. ).once()
  55. flexmock(module.os.path).should_call('join').with_args(
  56. '/run',
  57. 'bootstrap',
  58. 'manifest.json',
  59. ).once()
  60. flexmock(module.os.path).should_call('join').with_args(
  61. '/source',
  62. 'bootstrap',
  63. 'manifest.json',
  64. ).once()
  65. manifest_missing_extract_process = flexmock(
  66. stdout=flexmock(read=lambda: None),
  67. )
  68. manifest_found_extract_process = flexmock(
  69. stdout=flexmock(
  70. read=lambda: '{"config_paths": ["/borgmatic/config.yaml"]}',
  71. ),
  72. )
  73. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  74. manifest_missing_extract_process,
  75. ).and_return(manifest_missing_extract_process).and_return(manifest_found_extract_process)
  76. assert module.load_config_paths_from_archive(
  77. 'repo',
  78. 'archive',
  79. config={},
  80. local_borg_version=flexmock(),
  81. global_arguments=flexmock(dry_run=False),
  82. borgmatic_runtime_directory='/run',
  83. ) == ['/borgmatic/config.yaml']
  84. def test_load_config_paths_from_archive_with_missing_manifest_raises_value_error():
  85. flexmock(module.borgmatic.config.paths).should_receive(
  86. 'make_runtime_directory_glob',
  87. ).replace_with(lambda path: path)
  88. flexmock(module.borgmatic.config.paths).should_receive(
  89. 'get_borgmatic_source_directory',
  90. ).and_return('/source')
  91. extract_process = flexmock(stdout=flexmock(read=lambda: ''))
  92. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  93. extract_process,
  94. )
  95. with pytest.raises(ValueError):
  96. module.load_config_paths_from_archive(
  97. 'repo',
  98. 'archive',
  99. config={},
  100. local_borg_version=flexmock(),
  101. global_arguments=flexmock(dry_run=False),
  102. borgmatic_runtime_directory='/run',
  103. )
  104. def test_load_config_paths_from_archive_with_broken_json_raises_value_error():
  105. flexmock(module.borgmatic.config.paths).should_receive(
  106. 'make_runtime_directory_glob',
  107. ).replace_with(lambda path: path)
  108. flexmock(module.borgmatic.config.paths).should_receive(
  109. 'get_borgmatic_source_directory',
  110. ).and_return('/source')
  111. extract_process = flexmock(
  112. stdout=flexmock(read=lambda: '{"config_paths": ["/oops'),
  113. )
  114. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  115. extract_process,
  116. )
  117. with pytest.raises(ValueError):
  118. module.load_config_paths_from_archive(
  119. 'repo',
  120. 'archive',
  121. config={},
  122. local_borg_version=flexmock(),
  123. global_arguments=flexmock(dry_run=False),
  124. borgmatic_runtime_directory='/run',
  125. )
  126. def test_load_config_paths_from_archive_with_json_missing_key_raises_value_error():
  127. flexmock(module.borgmatic.config.paths).should_receive(
  128. 'make_runtime_directory_glob',
  129. ).replace_with(lambda path: path)
  130. flexmock(module.borgmatic.config.paths).should_receive(
  131. 'get_borgmatic_source_directory',
  132. ).and_return('/source')
  133. extract_process = flexmock(
  134. stdout=flexmock(read=lambda: '{}'),
  135. )
  136. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  137. extract_process,
  138. )
  139. with pytest.raises(ValueError):
  140. module.load_config_paths_from_archive(
  141. 'repo',
  142. 'archive',
  143. config={},
  144. local_borg_version=flexmock(),
  145. global_arguments=flexmock(dry_run=False),
  146. borgmatic_runtime_directory='/run',
  147. )
  148. def test_run_bootstrap_does_not_raise():
  149. flexmock(module).should_receive('make_bootstrap_config').and_return({})
  150. flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').and_return(
  151. 'archive',
  152. )
  153. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  154. flexmock(),
  155. )
  156. flexmock(module).should_receive('load_config_paths_from_archive').and_return(
  157. ['/borgmatic/config.yaml']
  158. )
  159. bootstrap_arguments = flexmock(
  160. repository='repo',
  161. archive='archive',
  162. destination='dest',
  163. strip_components=1,
  164. user_runtime_directory='/borgmatic',
  165. ssh_command=None,
  166. local_path='borg7',
  167. remote_path='borg8',
  168. progress=None,
  169. )
  170. global_arguments = flexmock(
  171. dry_run=False,
  172. )
  173. local_borg_version = flexmock()
  174. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  175. flexmock(),
  176. )
  177. flexmock(module.borgmatic.config.paths).should_receive(
  178. 'make_runtime_directory_glob',
  179. ).replace_with(lambda path: path)
  180. extract_process = flexmock(
  181. stdout=flexmock(
  182. read=lambda: '{"config_paths": ["borgmatic/config.yaml"]}',
  183. ),
  184. )
  185. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').and_return(
  186. extract_process,
  187. ).once()
  188. module.run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version)
  189. def test_run_bootstrap_translates_ssh_command_argument_to_config():
  190. config = {}
  191. flexmock(module).should_receive('make_bootstrap_config').and_return(config)
  192. flexmock(module.borgmatic.borg.repo_list).should_receive('resolve_archive_name').with_args(
  193. 'repo',
  194. 'archive',
  195. config,
  196. object,
  197. object,
  198. local_path='borg7',
  199. remote_path='borg8',
  200. ).and_return('archive')
  201. flexmock(module.borgmatic.config.paths).should_receive('Runtime_directory').and_return(
  202. flexmock(),
  203. )
  204. flexmock(module).should_receive('load_config_paths_from_archive').and_return(
  205. ['/borgmatic/config.yaml']
  206. )
  207. bootstrap_arguments = flexmock(
  208. repository='repo',
  209. archive='archive',
  210. destination='dest',
  211. strip_components=1,
  212. user_runtime_directory='/borgmatic',
  213. ssh_command='ssh -i key',
  214. local_path='borg7',
  215. remote_path='borg8',
  216. progress=None,
  217. )
  218. global_arguments = flexmock(
  219. dry_run=False,
  220. )
  221. local_borg_version = flexmock()
  222. flexmock(module.borgmatic.config.paths).should_receive(
  223. 'make_runtime_directory_glob',
  224. ).replace_with(lambda path: path)
  225. extract_process = flexmock(
  226. stdout=flexmock(
  227. read=lambda: '{"config_paths": ["borgmatic/config.yaml"]}',
  228. ),
  229. )
  230. flexmock(module.borgmatic.borg.extract).should_receive('extract_archive').with_args(
  231. False,
  232. 'repo',
  233. 'archive',
  234. object,
  235. {'progress': False},
  236. object,
  237. object,
  238. extract_to_stdout=False,
  239. destination_path='dest',
  240. strip_components=1,
  241. local_path='borg7',
  242. remote_path='borg8',
  243. ).and_return(extract_process).once()
  244. module.run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version)