浏览代码

use exit_code_indicates_error and modify it to accept a command

Divyansh Singh 2 年之前
父节点
当前提交
bd235f0426
共有 4 个文件被更改,包括 38 次插入42 次删除
  1. 1 1
      borgmatic/borg/create.py
  2. 7 13
      borgmatic/execute.py
  3. 4 4
      tests/integration/test_execute.py
  4. 26 24
      tests/unit/test_execute.py

+ 1 - 1
borgmatic/borg/create.py

@@ -291,7 +291,7 @@ def collect_special_file_paths(
         capture_stderr=True,
         working_directory=working_directory,
         extra_environment=borg_environment,
-        raise_on_exit_code_one=False,
+        treat_exit_code_warning_as_error=False,
     )
 
     paths = tuple(

+ 7 - 13
borgmatic/execute.py

@@ -11,7 +11,7 @@ ERROR_OUTPUT_MAX_LINE_COUNT = 25
 BORG_ERROR_EXIT_CODE = 2
 
 
-def exit_code_indicates_error(process, exit_code, borg_local_path=None):
+def exit_code_indicates_error(command, exit_code, borg_local_path=None):
     '''
     Return True if the given exit code from running a command corresponds to an error. If a Borg
     local path is given and matches the process' command, then treat exit code 1 as a warning
@@ -20,8 +20,6 @@ def exit_code_indicates_error(process, exit_code, borg_local_path=None):
     if exit_code is None:
         return False
 
-    command = process.args.split(' ') if isinstance(process.args, str) else process.args
-
     if borg_local_path and command[0] == borg_local_path:
         return bool(exit_code < 0 or exit_code >= BORG_ERROR_EXIT_CODE)
 
@@ -121,8 +119,9 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
             if exit_code is None:
                 still_running = True
 
+            command = process.args.split(' ') if isinstance(process.args, str) else process.args
             # If any process errors, then raise accordingly.
-            if exit_code_indicates_error(process, exit_code, borg_local_path):
+            if exit_code_indicates_error(command, exit_code, borg_local_path):
                 # If an error occurs, include its output in the raised exception so that we don't
                 # inadvertently hide error output.
                 output_buffer = output_buffer_for_process(process, exclude_stdouts)
@@ -213,12 +212,7 @@ def execute_command(
 
 
 def execute_command_and_capture_output(
-    full_command,
-    capture_stderr=False,
-    shell=False,
-    extra_environment=None,
-    working_directory=None,
-    raise_on_exit_code_one=True,
+    full_command, capture_stderr=False, shell=False, extra_environment=None, working_directory=None,
 ):
     '''
     Execute the given command (a sequence of command/argument strings), capturing and returning its
@@ -244,10 +238,10 @@ def execute_command_and_capture_output(
             cwd=working_directory,
         )
         logger.warning('Command output: {}'.format(output))
-    except subprocess.CalledProcessError as e:
-        if raise_on_exit_code_one or e.returncode != 1:
+    except subprocess.CalledProcessError as error:
+        if exit_code_indicates_error(error.returncode):
             raise
-        output = e.output
+        output = error.output
         logger.warning('Command output: {}'.format(output))
 
     return output.decode() if output is not None else None

+ 4 - 4
tests/integration/test_execute.py

@@ -138,10 +138,10 @@ def test_log_outputs_kills_other_processes_when_one_errors():
 
     process = subprocess.Popen(['grep'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     flexmock(module).should_receive('exit_code_indicates_error').with_args(
-        process, None, 'borg'
+        ['grep'], None, 'borg'
     ).and_return(False)
     flexmock(module).should_receive('exit_code_indicates_error').with_args(
-        process, 2, 'borg'
+        ['grep'], 2, 'borg'
     ).and_return(True)
     other_process = subprocess.Popen(
         ['sleep', '2'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
@@ -245,10 +245,10 @@ def test_log_outputs_truncates_long_error_output():
 
     process = subprocess.Popen(['grep'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     flexmock(module).should_receive('exit_code_indicates_error').with_args(
-        process, None, 'borg'
+        ['grep'], None, 'borg'
     ).and_return(False)
     flexmock(module).should_receive('exit_code_indicates_error').with_args(
-        process, 2, 'borg'
+        ['grep'], 2, 'borg'
     ).and_return(True)
     flexmock(module).should_receive('output_buffer_for_process').and_return(process.stdout)
 

+ 26 - 24
tests/unit/test_execute.py

@@ -7,32 +7,32 @@ from borgmatic import execute as module
 
 
 @pytest.mark.parametrize(
-    'process,exit_code,borg_local_path,expected_result',
+    'command,exit_code,borg_local_path,expected_result',
     (
-        (flexmock(args=['grep']), 2, None, True),
-        (flexmock(args=['grep']), 2, 'borg', True),
-        (flexmock(args=['borg']), 2, 'borg', True),
-        (flexmock(args=['borg1']), 2, 'borg1', True),
-        (flexmock(args=['grep']), 1, None, True),
-        (flexmock(args=['grep']), 1, 'borg', True),
-        (flexmock(args=['borg']), 1, 'borg', False),
-        (flexmock(args=['borg1']), 1, 'borg1', False),
-        (flexmock(args=['grep']), 0, None, False),
-        (flexmock(args=['grep']), 0, 'borg', False),
-        (flexmock(args=['borg']), 0, 'borg', False),
-        (flexmock(args=['borg1']), 0, 'borg1', False),
+        (['grep'], 2, None, True),
+        (['grep'], 2, 'borg', True),
+        (['borg'], 2, 'borg', True),
+        (['borg1'], 2, 'borg1', True),
+        (['grep'], 1, None, True),
+        (['grep'], 1, 'borg', True),
+        (['borg'], 1, 'borg', False),
+        (['borg1'], 1, 'borg1', False),
+        (['grep'], 0, None, False),
+        (['grep'], 0, 'borg', False),
+        (['borg'], 0, 'borg', False),
+        (['borg1'], 0, 'borg1', False),
         # -9 exit code occurs when child process get SIGKILLed.
-        (flexmock(args=['grep']), -9, None, True),
-        (flexmock(args=['grep']), -9, 'borg', True),
-        (flexmock(args=['borg']), -9, 'borg', True),
-        (flexmock(args=['borg1']), -9, 'borg1', True),
-        (flexmock(args=['borg']), None, None, False),
+        (['grep'], -9, None, True),
+        (['grep'], -9, 'borg', True),
+        (['borg'], -9, 'borg', True),
+        (['borg1'], -9, 'borg1', True),
+        (['borg'], None, None, False),
     ),
 )
 def test_exit_code_indicates_error_respects_exit_code_and_borg_local_path(
-    process, exit_code, borg_local_path, expected_result
+    command, exit_code, borg_local_path, expected_result
 ):
-    assert module.exit_code_indicates_error(process, exit_code, borg_local_path) is expected_result
+    assert module.exit_code_indicates_error(command, exit_code, borg_local_path) is expected_result
 
 
 def test_command_for_process_converts_sequence_command_to_string():
@@ -239,7 +239,7 @@ def test_execute_command_and_capture_output_with_capture_stderr_returns_stderr()
     assert output == expected_output
 
 
-def test_execute_command_and_capture_output_returns_output_with_raise_on_exit_code_one_false():
+def test_execute_command_and_capture_output_returns_output_when_error_code_is_one():
     full_command = ['foo', 'bar']
     expected_output = '[]'
     err_output = b'[]'
@@ -247,22 +247,24 @@ def test_execute_command_and_capture_output_returns_output_with_raise_on_exit_co
     flexmock(module.subprocess).should_receive('check_output').with_args(
         full_command, stderr=None, shell=False, env=None, cwd=None
     ).and_raise(subprocess.CalledProcessError(1, full_command, err_output)).once()
+    flexmock(module).should_receive('exit_code_indicates_error').and_return(False).once()
 
-    output = module.execute_command_and_capture_output(full_command, raise_on_exit_code_one=False)
+    output = module.execute_command_and_capture_output(full_command)
 
     assert output == expected_output
 
 
-def test_execute_command_and_capture_output_returns_output_with_raise_on_exit_code_one_false_and_exit_code_not_one():
+def test_execute_command_and_capture_output_returns_output_when_error_code_not_one():
     full_command = ['foo', 'bar']
     expected_output = '[]'
     flexmock(module.os, environ={'a': 'b'})
     flexmock(module.subprocess).should_receive('check_output').with_args(
         full_command, stderr=None, shell=False, env=None, cwd=None
     ).and_raise(subprocess.CalledProcessError(2, full_command, expected_output)).once()
+    flexmock(module).should_receive('exit_code_indicates_error').and_return(True).once()
 
     with pytest.raises(subprocess.CalledProcessError):
-        module.execute_command_and_capture_output(full_command, raise_on_exit_code_one=False)
+        module.execute_command_and_capture_output(full_command)
 
 
 def test_execute_command_and_capture_output_returns_output_with_shell():