test_execute.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import pytest
  2. from flexmock import flexmock
  3. from borgmatic import execute as module
  4. @pytest.mark.parametrize(
  5. 'exit_code,error_on_warnings,expected_result',
  6. (
  7. (2, True, True),
  8. (2, False, True),
  9. (1, True, True),
  10. (1, False, False),
  11. (0, True, False),
  12. (0, False, False),
  13. ),
  14. )
  15. def test_exit_code_indicates_error_respects_exit_code_and_error_on_warnings(
  16. exit_code, error_on_warnings, expected_result
  17. ):
  18. assert (
  19. module.exit_code_indicates_error(exit_code, error_on_warnings=error_on_warnings)
  20. is expected_result
  21. )
  22. def test_execute_command_calls_full_command():
  23. full_command = ['foo', 'bar']
  24. flexmock(module.os, environ={'a': 'b'})
  25. flexmock(module.subprocess).should_receive('Popen').with_args(
  26. full_command,
  27. stdin=None,
  28. stdout=module.subprocess.PIPE,
  29. stderr=module.subprocess.STDOUT,
  30. shell=False,
  31. env=None,
  32. cwd=None,
  33. ).and_return(flexmock(stdout=None)).once()
  34. flexmock(module).should_receive('log_output')
  35. output = module.execute_command(full_command)
  36. assert output is None
  37. def test_execute_command_calls_full_command_with_output_file():
  38. full_command = ['foo', 'bar']
  39. output_file = flexmock(name='test')
  40. flexmock(module.os, environ={'a': 'b'})
  41. flexmock(module.subprocess).should_receive('Popen').with_args(
  42. full_command,
  43. stdin=None,
  44. stdout=output_file,
  45. stderr=module.subprocess.PIPE,
  46. shell=False,
  47. env=None,
  48. cwd=None,
  49. ).and_return(flexmock(stderr=None)).once()
  50. flexmock(module).should_receive('log_output')
  51. output = module.execute_command(full_command, output_file=output_file)
  52. assert output is None
  53. def test_execute_command_calls_full_command_with_input_file():
  54. full_command = ['foo', 'bar']
  55. input_file = flexmock(name='test')
  56. flexmock(module.os, environ={'a': 'b'})
  57. flexmock(module.subprocess).should_receive('Popen').with_args(
  58. full_command,
  59. stdin=input_file,
  60. stdout=module.subprocess.PIPE,
  61. stderr=module.subprocess.STDOUT,
  62. shell=False,
  63. env=None,
  64. cwd=None,
  65. ).and_return(flexmock(stdout=None)).once()
  66. flexmock(module).should_receive('log_output')
  67. output = module.execute_command(full_command, input_file=input_file)
  68. assert output is None
  69. def test_execute_command_calls_full_command_with_shell():
  70. full_command = ['foo', 'bar']
  71. flexmock(module.os, environ={'a': 'b'})
  72. flexmock(module.subprocess).should_receive('Popen').with_args(
  73. ' '.join(full_command),
  74. stdin=None,
  75. stdout=module.subprocess.PIPE,
  76. stderr=module.subprocess.STDOUT,
  77. shell=True,
  78. env=None,
  79. cwd=None,
  80. ).and_return(flexmock(stdout=None)).once()
  81. flexmock(module).should_receive('log_output')
  82. output = module.execute_command(full_command, shell=True)
  83. assert output is None
  84. def test_execute_command_calls_full_command_with_extra_environment():
  85. full_command = ['foo', 'bar']
  86. flexmock(module.os, environ={'a': 'b'})
  87. flexmock(module.subprocess).should_receive('Popen').with_args(
  88. full_command,
  89. stdin=None,
  90. stdout=module.subprocess.PIPE,
  91. stderr=module.subprocess.STDOUT,
  92. shell=False,
  93. env={'a': 'b', 'c': 'd'},
  94. cwd=None,
  95. ).and_return(flexmock(stdout=None)).once()
  96. flexmock(module).should_receive('log_output')
  97. output = module.execute_command(full_command, extra_environment={'c': 'd'})
  98. assert output is None
  99. def test_execute_command_calls_full_command_with_working_directory():
  100. full_command = ['foo', 'bar']
  101. flexmock(module.os, environ={'a': 'b'})
  102. flexmock(module.subprocess).should_receive('Popen').with_args(
  103. full_command,
  104. stdin=None,
  105. stdout=module.subprocess.PIPE,
  106. stderr=module.subprocess.STDOUT,
  107. shell=False,
  108. env=None,
  109. cwd='/working',
  110. ).and_return(flexmock(stdout=None)).once()
  111. flexmock(module).should_receive('log_output')
  112. output = module.execute_command(full_command, working_directory='/working')
  113. assert output is None
  114. def test_execute_command_without_run_to_completion_returns_process():
  115. full_command = ['foo', 'bar']
  116. process = flexmock()
  117. flexmock(module.os, environ={'a': 'b'})
  118. flexmock(module.subprocess).should_receive('Popen').with_args(
  119. full_command,
  120. stdin=None,
  121. stdout=module.subprocess.PIPE,
  122. stderr=module.subprocess.STDOUT,
  123. shell=False,
  124. env=None,
  125. cwd=None,
  126. ).and_return(process).once()
  127. flexmock(module).should_receive('log_output')
  128. assert module.execute_command(full_command, run_to_completion=False) == process
  129. def test_execute_command_captures_output():
  130. full_command = ['foo', 'bar']
  131. expected_output = '[]'
  132. flexmock(module.os, environ={'a': 'b'})
  133. flexmock(module.subprocess).should_receive('check_output').with_args(
  134. full_command, shell=False, env=None, cwd=None
  135. ).and_return(flexmock(decode=lambda: expected_output)).once()
  136. output = module.execute_command(full_command, output_log_level=None)
  137. assert output == expected_output
  138. def test_execute_command_captures_output_with_shell():
  139. full_command = ['foo', 'bar']
  140. expected_output = '[]'
  141. flexmock(module.os, environ={'a': 'b'})
  142. flexmock(module.subprocess).should_receive('check_output').with_args(
  143. full_command, shell=True, env=None, cwd=None
  144. ).and_return(flexmock(decode=lambda: expected_output)).once()
  145. output = module.execute_command(full_command, output_log_level=None, shell=True)
  146. assert output == expected_output
  147. def test_execute_command_captures_output_with_extra_environment():
  148. full_command = ['foo', 'bar']
  149. expected_output = '[]'
  150. flexmock(module.os, environ={'a': 'b'})
  151. flexmock(module.subprocess).should_receive('check_output').with_args(
  152. full_command, shell=False, env={'a': 'b', 'c': 'd'}, cwd=None
  153. ).and_return(flexmock(decode=lambda: expected_output)).once()
  154. output = module.execute_command(
  155. full_command, output_log_level=None, shell=False, extra_environment={'c': 'd'}
  156. )
  157. assert output == expected_output
  158. def test_execute_command_captures_output_with_working_directory():
  159. full_command = ['foo', 'bar']
  160. expected_output = '[]'
  161. flexmock(module.os, environ={'a': 'b'})
  162. flexmock(module.subprocess).should_receive('check_output').with_args(
  163. full_command, shell=False, env=None, cwd='/working'
  164. ).and_return(flexmock(decode=lambda: expected_output)).once()
  165. output = module.execute_command(
  166. full_command, output_log_level=None, shell=False, working_directory='/working'
  167. )
  168. assert output == expected_output
  169. def test_execute_command_without_capture_does_not_raise_on_success():
  170. flexmock(module.subprocess).should_receive('check_call').and_raise(
  171. module.subprocess.CalledProcessError(0, 'borg init')
  172. )
  173. module.execute_command_without_capture(('borg', 'init'))
  174. def test_execute_command_without_capture_does_not_raise_on_warning():
  175. flexmock(module).should_receive('exit_code_indicates_error').and_return(False)
  176. flexmock(module.subprocess).should_receive('check_call').and_raise(
  177. module.subprocess.CalledProcessError(1, 'borg init')
  178. )
  179. module.execute_command_without_capture(('borg', 'init'))
  180. def test_execute_command_without_capture_raises_on_error():
  181. flexmock(module).should_receive('exit_code_indicates_error').and_return(True)
  182. flexmock(module.subprocess).should_receive('check_call').and_raise(
  183. module.subprocess.CalledProcessError(2, 'borg init')
  184. )
  185. with pytest.raises(module.subprocess.CalledProcessError):
  186. module.execute_command_without_capture(('borg', 'init'))