2
0

test_execute.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. import subprocess
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic import execute as module
  5. @pytest.mark.parametrize(
  6. 'command,exit_code,borg_local_path,borg_exit_codes,expected_result',
  7. (
  8. (['grep'], 2, None, None, module.Exit_status.ERROR),
  9. (['grep'], 2, 'borg', None, module.Exit_status.ERROR),
  10. (['borg'], 2, 'borg', None, module.Exit_status.ERROR),
  11. (['borg1'], 2, 'borg1', None, module.Exit_status.ERROR),
  12. (['grep'], 1, None, None, module.Exit_status.ERROR),
  13. (['grep'], 1, 'borg', None, module.Exit_status.ERROR),
  14. (['borg'], 1, 'borg', None, module.Exit_status.WARNING),
  15. (['borg1'], 1, 'borg1', None, module.Exit_status.WARNING),
  16. (['grep'], 100, None, None, module.Exit_status.ERROR),
  17. (['grep'], 100, 'borg', None, module.Exit_status.ERROR),
  18. (['borg'], 100, 'borg', None, module.Exit_status.WARNING),
  19. (['borg1'], 100, 'borg1', None, module.Exit_status.WARNING),
  20. (['grep'], 0, None, None, module.Exit_status.SUCCESS),
  21. (['grep'], 0, 'borg', None, module.Exit_status.SUCCESS),
  22. (['borg'], 0, 'borg', None, module.Exit_status.SUCCESS),
  23. (['borg1'], 0, 'borg1', None, module.Exit_status.SUCCESS),
  24. # -9 exit code occurs when child process get SIGKILLed.
  25. (['grep'], -9, None, None, module.Exit_status.ERROR),
  26. (['grep'], -9, 'borg', None, module.Exit_status.ERROR),
  27. (['borg'], -9, 'borg', None, module.Exit_status.ERROR),
  28. (['borg1'], -9, 'borg1', None, module.Exit_status.ERROR),
  29. (['borg'], None, None, None, module.Exit_status.STILL_RUNNING),
  30. (['borg'], 1, 'borg', [], module.Exit_status.WARNING),
  31. (['borg'], 1, 'borg', [{}], module.Exit_status.WARNING),
  32. (['borg'], 1, 'borg', [{'code': 1}], module.Exit_status.WARNING),
  33. (['grep'], 1, 'borg', [{'code': 100, 'treat_as': 'error'}], module.Exit_status.ERROR),
  34. (['borg'], 1, 'borg', [{'code': 100, 'treat_as': 'error'}], module.Exit_status.WARNING),
  35. (['borg'], 1, 'borg', [{'code': 1, 'treat_as': 'error'}], module.Exit_status.ERROR),
  36. (['borg'], 2, 'borg', [{'code': 99, 'treat_as': 'warning'}], module.Exit_status.ERROR),
  37. (['borg'], 2, 'borg', [{'code': 2, 'treat_as': 'warning'}], module.Exit_status.WARNING),
  38. (['borg'], 100, 'borg', [{'code': 1, 'treat_as': 'error'}], module.Exit_status.WARNING),
  39. (['borg'], 100, 'borg', [{'code': 100, 'treat_as': 'error'}], module.Exit_status.ERROR),
  40. ),
  41. )
  42. def test_interpret_exit_code_respects_exit_code_and_borg_local_path(
  43. command, exit_code, borg_local_path, borg_exit_codes, expected_result
  44. ):
  45. assert (
  46. module.interpret_exit_code(command, exit_code, borg_local_path, borg_exit_codes)
  47. is expected_result
  48. )
  49. def test_command_for_process_converts_sequence_command_to_string():
  50. process = flexmock(args=['foo', 'bar', 'baz'])
  51. assert module.command_for_process(process) == 'foo bar baz'
  52. def test_command_for_process_passes_through_string_command():
  53. process = flexmock(args='foo bar baz')
  54. assert module.command_for_process(process) == 'foo bar baz'
  55. def test_output_buffer_for_process_returns_stderr_when_stdout_excluded():
  56. stdout = flexmock()
  57. stderr = flexmock()
  58. process = flexmock(stdout=stdout, stderr=stderr)
  59. assert module.output_buffer_for_process(process, exclude_stdouts=[flexmock(), stdout]) == stderr
  60. def test_output_buffer_for_process_returns_stdout_when_not_excluded():
  61. stdout = flexmock()
  62. process = flexmock(stdout=stdout)
  63. assert (
  64. module.output_buffer_for_process(process, exclude_stdouts=[flexmock(), flexmock()])
  65. == stdout
  66. )
  67. def test_append_last_lines_under_max_line_count_appends():
  68. last_lines = ['last']
  69. flexmock(module.logger).should_receive('log').once()
  70. module.append_last_lines(
  71. last_lines, captured_output=flexmock(), line='line', output_log_level=flexmock()
  72. )
  73. assert last_lines == ['last', 'line']
  74. def test_append_last_lines_over_max_line_count_trims_and_appends():
  75. original_last_lines = [str(number) for number in range(0, module.ERROR_OUTPUT_MAX_LINE_COUNT)]
  76. last_lines = list(original_last_lines)
  77. flexmock(module.logger).should_receive('log').once()
  78. module.append_last_lines(
  79. last_lines, captured_output=flexmock(), line='line', output_log_level=flexmock()
  80. )
  81. assert last_lines == original_last_lines[1:] + ['line']
  82. def test_append_last_lines_with_output_log_level_none_appends_captured_output():
  83. last_lines = ['last']
  84. captured_output = ['captured']
  85. flexmock(module.logger).should_receive('log').never()
  86. module.append_last_lines(
  87. last_lines, captured_output=captured_output, line='line', output_log_level=None
  88. )
  89. assert captured_output == ['captured', 'line']
  90. @pytest.mark.parametrize(
  91. 'full_command,input_file,output_file,environment,expected_result',
  92. (
  93. (('foo', 'bar'), None, None, None, 'foo bar'),
  94. (('foo', 'bar'), flexmock(name='input'), None, None, 'foo bar < input'),
  95. (('foo', 'bar'), None, flexmock(name='output'), None, 'foo bar > output'),
  96. (
  97. ('foo', 'bar'),
  98. flexmock(name='input'),
  99. flexmock(name='output'),
  100. None,
  101. 'foo bar < input > output',
  102. ),
  103. (
  104. ('foo', 'bar'),
  105. None,
  106. None,
  107. {'DBPASS': 'secret', 'OTHER': 'thing'},
  108. 'DBPASS=*** OTHER=*** foo bar',
  109. ),
  110. ),
  111. )
  112. def test_log_command_logs_command_constructed_from_arguments(
  113. full_command, input_file, output_file, environment, expected_result
  114. ):
  115. flexmock(module.logger).should_receive('debug').with_args(expected_result).once()
  116. module.log_command(full_command, input_file, output_file, environment)
  117. def test_execute_command_calls_full_command():
  118. full_command = ['foo', 'bar']
  119. flexmock(module).should_receive('log_command')
  120. flexmock(module.os, environ={'a': 'b'})
  121. flexmock(module.subprocess).should_receive('Popen').with_args(
  122. full_command,
  123. stdin=None,
  124. stdout=module.subprocess.PIPE,
  125. stderr=module.subprocess.STDOUT,
  126. shell=False,
  127. env=None,
  128. cwd=None,
  129. ).and_return(flexmock(stdout=None)).once()
  130. flexmock(module).should_receive('log_outputs')
  131. output = module.execute_command(full_command)
  132. assert output is None
  133. def test_execute_command_calls_full_command_with_output_file():
  134. full_command = ['foo', 'bar']
  135. output_file = flexmock(name='test')
  136. flexmock(module).should_receive('log_command')
  137. flexmock(module.os, environ={'a': 'b'})
  138. flexmock(module.subprocess).should_receive('Popen').with_args(
  139. full_command,
  140. stdin=None,
  141. stdout=output_file,
  142. stderr=module.subprocess.PIPE,
  143. shell=False,
  144. env=None,
  145. cwd=None,
  146. ).and_return(flexmock(stderr=None)).once()
  147. flexmock(module).should_receive('log_outputs')
  148. output = module.execute_command(full_command, output_file=output_file)
  149. assert output is None
  150. def test_execute_command_calls_full_command_without_capturing_output():
  151. full_command = ['foo', 'bar']
  152. flexmock(module).should_receive('log_command')
  153. flexmock(module.os, environ={'a': 'b'})
  154. flexmock(module.subprocess).should_receive('Popen').with_args(
  155. full_command, stdin=None, stdout=None, stderr=None, shell=False, env=None, cwd=None
  156. ).and_return(flexmock(wait=lambda: 0)).once()
  157. flexmock(module).should_receive('interpret_exit_code').and_return(module.Exit_status.SUCCESS)
  158. flexmock(module).should_receive('log_outputs')
  159. output = module.execute_command(full_command, output_file=module.DO_NOT_CAPTURE)
  160. assert output is None
  161. def test_execute_command_calls_full_command_with_input_file():
  162. full_command = ['foo', 'bar']
  163. input_file = flexmock(name='test')
  164. flexmock(module).should_receive('log_command')
  165. flexmock(module.os, environ={'a': 'b'})
  166. flexmock(module.subprocess).should_receive('Popen').with_args(
  167. full_command,
  168. stdin=input_file,
  169. stdout=module.subprocess.PIPE,
  170. stderr=module.subprocess.STDOUT,
  171. shell=False,
  172. env=None,
  173. cwd=None,
  174. ).and_return(flexmock(stdout=None)).once()
  175. flexmock(module).should_receive('log_outputs')
  176. output = module.execute_command(full_command, input_file=input_file)
  177. assert output is None
  178. def test_execute_command_calls_full_command_with_shell():
  179. full_command = ['foo', 'bar']
  180. flexmock(module).should_receive('log_command')
  181. flexmock(module.os, environ={'a': 'b'})
  182. flexmock(module.subprocess).should_receive('Popen').with_args(
  183. ' '.join(full_command),
  184. stdin=None,
  185. stdout=module.subprocess.PIPE,
  186. stderr=module.subprocess.STDOUT,
  187. shell=True,
  188. env=None,
  189. cwd=None,
  190. ).and_return(flexmock(stdout=None)).once()
  191. flexmock(module).should_receive('log_outputs')
  192. output = module.execute_command(full_command, shell=True)
  193. assert output is None
  194. def test_execute_command_calls_full_command_with_extra_environment():
  195. full_command = ['foo', 'bar']
  196. flexmock(module).should_receive('log_command')
  197. flexmock(module.os, environ={'a': 'b'})
  198. flexmock(module.subprocess).should_receive('Popen').with_args(
  199. full_command,
  200. stdin=None,
  201. stdout=module.subprocess.PIPE,
  202. stderr=module.subprocess.STDOUT,
  203. shell=False,
  204. env={'a': 'b', 'c': 'd'},
  205. cwd=None,
  206. ).and_return(flexmock(stdout=None)).once()
  207. flexmock(module).should_receive('log_outputs')
  208. output = module.execute_command(full_command, extra_environment={'c': 'd'})
  209. assert output is None
  210. def test_execute_command_calls_full_command_with_working_directory():
  211. full_command = ['foo', 'bar']
  212. flexmock(module).should_receive('log_command')
  213. flexmock(module.os, environ={'a': 'b'})
  214. flexmock(module.subprocess).should_receive('Popen').with_args(
  215. full_command,
  216. stdin=None,
  217. stdout=module.subprocess.PIPE,
  218. stderr=module.subprocess.STDOUT,
  219. shell=False,
  220. env=None,
  221. cwd='/working',
  222. ).and_return(flexmock(stdout=None)).once()
  223. flexmock(module).should_receive('log_outputs')
  224. output = module.execute_command(full_command, working_directory='/working')
  225. assert output is None
  226. def test_execute_command_without_run_to_completion_returns_process():
  227. full_command = ['foo', 'bar']
  228. process = flexmock()
  229. flexmock(module).should_receive('log_command')
  230. flexmock(module.os, environ={'a': 'b'})
  231. flexmock(module.subprocess).should_receive('Popen').with_args(
  232. full_command,
  233. stdin=None,
  234. stdout=module.subprocess.PIPE,
  235. stderr=module.subprocess.STDOUT,
  236. shell=False,
  237. env=None,
  238. cwd=None,
  239. ).and_return(process).once()
  240. flexmock(module).should_receive('log_outputs')
  241. assert module.execute_command(full_command, run_to_completion=False) == process
  242. def test_execute_command_and_capture_output_returns_stdout():
  243. full_command = ['foo', 'bar']
  244. expected_output = '[]'
  245. flexmock(module).should_receive('log_command')
  246. flexmock(module.os, environ={'a': 'b'})
  247. flexmock(module.subprocess).should_receive('check_output').with_args(
  248. full_command, stderr=None, shell=False, env=None, cwd=None
  249. ).and_return(flexmock(decode=lambda: expected_output)).once()
  250. output = module.execute_command_and_capture_output(full_command)
  251. assert output == expected_output
  252. def test_execute_command_and_capture_output_with_capture_stderr_returns_stderr():
  253. full_command = ['foo', 'bar']
  254. expected_output = '[]'
  255. flexmock(module).should_receive('log_command')
  256. flexmock(module.os, environ={'a': 'b'})
  257. flexmock(module.subprocess).should_receive('check_output').with_args(
  258. full_command, stderr=module.subprocess.STDOUT, shell=False, env=None, cwd=None
  259. ).and_return(flexmock(decode=lambda: expected_output)).once()
  260. output = module.execute_command_and_capture_output(full_command, capture_stderr=True)
  261. assert output == expected_output
  262. def test_execute_command_and_capture_output_returns_output_when_process_error_is_not_considered_an_error():
  263. full_command = ['foo', 'bar']
  264. expected_output = '[]'
  265. err_output = b'[]'
  266. flexmock(module).should_receive('log_command')
  267. flexmock(module.os, environ={'a': 'b'})
  268. flexmock(module.subprocess).should_receive('check_output').with_args(
  269. full_command, stderr=None, shell=False, env=None, cwd=None
  270. ).and_raise(subprocess.CalledProcessError(1, full_command, err_output)).once()
  271. flexmock(module).should_receive('interpret_exit_code').and_return(
  272. module.Exit_status.SUCCESS
  273. ).once()
  274. output = module.execute_command_and_capture_output(full_command)
  275. assert output == expected_output
  276. def test_execute_command_and_capture_output_raises_when_command_errors():
  277. full_command = ['foo', 'bar']
  278. expected_output = '[]'
  279. flexmock(module).should_receive('log_command')
  280. flexmock(module.os, environ={'a': 'b'})
  281. flexmock(module.subprocess).should_receive('check_output').with_args(
  282. full_command, stderr=None, shell=False, env=None, cwd=None
  283. ).and_raise(subprocess.CalledProcessError(2, full_command, expected_output)).once()
  284. flexmock(module).should_receive('interpret_exit_code').and_return(
  285. module.Exit_status.ERROR
  286. ).once()
  287. with pytest.raises(subprocess.CalledProcessError):
  288. module.execute_command_and_capture_output(full_command)
  289. def test_execute_command_and_capture_output_returns_output_with_shell():
  290. full_command = ['foo', 'bar']
  291. expected_output = '[]'
  292. flexmock(module).should_receive('log_command')
  293. flexmock(module.os, environ={'a': 'b'})
  294. flexmock(module.subprocess).should_receive('check_output').with_args(
  295. 'foo bar', stderr=None, shell=True, env=None, cwd=None
  296. ).and_return(flexmock(decode=lambda: expected_output)).once()
  297. output = module.execute_command_and_capture_output(full_command, shell=True)
  298. assert output == expected_output
  299. def test_execute_command_and_capture_output_returns_output_with_extra_environment():
  300. full_command = ['foo', 'bar']
  301. expected_output = '[]'
  302. flexmock(module).should_receive('log_command')
  303. flexmock(module.os, environ={'a': 'b'})
  304. flexmock(module.subprocess).should_receive('check_output').with_args(
  305. full_command,
  306. stderr=None,
  307. shell=False,
  308. env={'a': 'b', 'c': 'd'},
  309. cwd=None,
  310. ).and_return(flexmock(decode=lambda: expected_output)).once()
  311. output = module.execute_command_and_capture_output(
  312. full_command, shell=False, extra_environment={'c': 'd'}
  313. )
  314. assert output == expected_output
  315. def test_execute_command_and_capture_output_returns_output_with_working_directory():
  316. full_command = ['foo', 'bar']
  317. expected_output = '[]'
  318. flexmock(module).should_receive('log_command')
  319. flexmock(module.os, environ={'a': 'b'})
  320. flexmock(module.subprocess).should_receive('check_output').with_args(
  321. full_command, stderr=None, shell=False, env=None, cwd='/working'
  322. ).and_return(flexmock(decode=lambda: expected_output)).once()
  323. output = module.execute_command_and_capture_output(
  324. full_command, shell=False, working_directory='/working'
  325. )
  326. assert output == expected_output
  327. def test_execute_command_with_processes_calls_full_command():
  328. full_command = ['foo', 'bar']
  329. processes = (flexmock(),)
  330. flexmock(module).should_receive('log_command')
  331. flexmock(module.os, environ={'a': 'b'})
  332. flexmock(module.subprocess).should_receive('Popen').with_args(
  333. full_command,
  334. stdin=None,
  335. stdout=module.subprocess.PIPE,
  336. stderr=module.subprocess.STDOUT,
  337. shell=False,
  338. env=None,
  339. cwd=None,
  340. ).and_return(flexmock(stdout=None)).once()
  341. flexmock(module).should_receive('log_outputs')
  342. output = module.execute_command_with_processes(full_command, processes)
  343. assert output is None
  344. def test_execute_command_with_processes_returns_output_with_output_log_level_none():
  345. full_command = ['foo', 'bar']
  346. processes = (flexmock(),)
  347. flexmock(module).should_receive('log_command')
  348. flexmock(module.os, environ={'a': 'b'})
  349. process = flexmock(stdout=None)
  350. flexmock(module.subprocess).should_receive('Popen').with_args(
  351. full_command,
  352. stdin=None,
  353. stdout=module.subprocess.PIPE,
  354. stderr=module.subprocess.STDOUT,
  355. shell=False,
  356. env=None,
  357. cwd=None,
  358. ).and_return(process).once()
  359. flexmock(module).should_receive('log_outputs').and_return({process: 'out'})
  360. output = module.execute_command_with_processes(full_command, processes, output_log_level=None)
  361. assert output == 'out'
  362. def test_execute_command_with_processes_calls_full_command_with_output_file():
  363. full_command = ['foo', 'bar']
  364. processes = (flexmock(),)
  365. output_file = flexmock(name='test')
  366. flexmock(module).should_receive('log_command')
  367. flexmock(module.os, environ={'a': 'b'})
  368. flexmock(module.subprocess).should_receive('Popen').with_args(
  369. full_command,
  370. stdin=None,
  371. stdout=output_file,
  372. stderr=module.subprocess.PIPE,
  373. shell=False,
  374. env=None,
  375. cwd=None,
  376. ).and_return(flexmock(stderr=None)).once()
  377. flexmock(module).should_receive('log_outputs')
  378. output = module.execute_command_with_processes(full_command, processes, output_file=output_file)
  379. assert output is None
  380. def test_execute_command_with_processes_calls_full_command_without_capturing_output():
  381. full_command = ['foo', 'bar']
  382. processes = (flexmock(),)
  383. flexmock(module).should_receive('log_command')
  384. flexmock(module.os, environ={'a': 'b'})
  385. flexmock(module.subprocess).should_receive('Popen').with_args(
  386. full_command, stdin=None, stdout=None, stderr=None, shell=False, env=None, cwd=None
  387. ).and_return(flexmock(wait=lambda: 0)).once()
  388. flexmock(module).should_receive('interpret_exit_code').and_return(module.Exit_status.SUCCESS)
  389. flexmock(module).should_receive('log_outputs')
  390. output = module.execute_command_with_processes(
  391. full_command, processes, output_file=module.DO_NOT_CAPTURE
  392. )
  393. assert output is None
  394. def test_execute_command_with_processes_calls_full_command_with_input_file():
  395. full_command = ['foo', 'bar']
  396. processes = (flexmock(),)
  397. input_file = flexmock(name='test')
  398. flexmock(module).should_receive('log_command')
  399. flexmock(module.os, environ={'a': 'b'})
  400. flexmock(module.subprocess).should_receive('Popen').with_args(
  401. full_command,
  402. stdin=input_file,
  403. stdout=module.subprocess.PIPE,
  404. stderr=module.subprocess.STDOUT,
  405. shell=False,
  406. env=None,
  407. cwd=None,
  408. ).and_return(flexmock(stdout=None)).once()
  409. flexmock(module).should_receive('log_outputs')
  410. output = module.execute_command_with_processes(full_command, processes, input_file=input_file)
  411. assert output is None
  412. def test_execute_command_with_processes_calls_full_command_with_shell():
  413. full_command = ['foo', 'bar']
  414. processes = (flexmock(),)
  415. flexmock(module).should_receive('log_command')
  416. flexmock(module.os, environ={'a': 'b'})
  417. flexmock(module.subprocess).should_receive('Popen').with_args(
  418. ' '.join(full_command),
  419. stdin=None,
  420. stdout=module.subprocess.PIPE,
  421. stderr=module.subprocess.STDOUT,
  422. shell=True,
  423. env=None,
  424. cwd=None,
  425. ).and_return(flexmock(stdout=None)).once()
  426. flexmock(module).should_receive('log_outputs')
  427. output = module.execute_command_with_processes(full_command, processes, shell=True)
  428. assert output is None
  429. def test_execute_command_with_processes_calls_full_command_with_extra_environment():
  430. full_command = ['foo', 'bar']
  431. processes = (flexmock(),)
  432. flexmock(module).should_receive('log_command')
  433. flexmock(module.os, environ={'a': 'b'})
  434. flexmock(module.subprocess).should_receive('Popen').with_args(
  435. full_command,
  436. stdin=None,
  437. stdout=module.subprocess.PIPE,
  438. stderr=module.subprocess.STDOUT,
  439. shell=False,
  440. env={'a': 'b', 'c': 'd'},
  441. cwd=None,
  442. ).and_return(flexmock(stdout=None)).once()
  443. flexmock(module).should_receive('log_outputs')
  444. output = module.execute_command_with_processes(
  445. full_command, processes, extra_environment={'c': 'd'}
  446. )
  447. assert output is None
  448. def test_execute_command_with_processes_calls_full_command_with_working_directory():
  449. full_command = ['foo', 'bar']
  450. processes = (flexmock(),)
  451. flexmock(module).should_receive('log_command')
  452. flexmock(module.os, environ={'a': 'b'})
  453. flexmock(module.subprocess).should_receive('Popen').with_args(
  454. full_command,
  455. stdin=None,
  456. stdout=module.subprocess.PIPE,
  457. stderr=module.subprocess.STDOUT,
  458. shell=False,
  459. env=None,
  460. cwd='/working',
  461. ).and_return(flexmock(stdout=None)).once()
  462. flexmock(module).should_receive('log_outputs')
  463. output = module.execute_command_with_processes(
  464. full_command, processes, working_directory='/working'
  465. )
  466. assert output is None
  467. def test_execute_command_with_processes_kills_processes_on_error():
  468. full_command = ['foo', 'bar']
  469. flexmock(module).should_receive('log_command')
  470. process = flexmock(stdout=flexmock(read=lambda count: None))
  471. process.should_receive('poll')
  472. process.should_receive('kill').once()
  473. processes = (process,)
  474. flexmock(module.os, environ={'a': 'b'})
  475. flexmock(module.subprocess).should_receive('Popen').with_args(
  476. full_command,
  477. stdin=None,
  478. stdout=module.subprocess.PIPE,
  479. stderr=module.subprocess.STDOUT,
  480. shell=False,
  481. env=None,
  482. cwd=None,
  483. ).and_raise(subprocess.CalledProcessError(1, full_command, 'error')).once()
  484. flexmock(module).should_receive('log_outputs').never()
  485. with pytest.raises(subprocess.CalledProcessError):
  486. module.execute_command_with_processes(full_command, processes)