Ver Fonte

Do not treat Borg warnings (exit code 1) as failures (#204).

Dan Helfman há 5 anos atrás
pai
commit
ccbd0b608b
6 ficheiros alterados com 41 adições e 6 exclusões
  1. 1 0
      NEWS
  2. 6 2
      borgmatic/borg/init.py
  3. 2 1
      borgmatic/execute.py
  4. 1 1
      setup.py
  5. 12 2
      tests/integration/test_execute.py
  6. 19 0
      tests/unit/borg/test_init.py

+ 1 - 0
NEWS

@@ -1,4 +1,5 @@
 1.3.14
+ * #204: Do not treat Borg warnings (exit code 1) as failures.
  * When validating configuration files, require strings instead of allowing any scalar type.
 
 1.3.13

+ 6 - 2
borgmatic/borg/init.py

@@ -1,7 +1,7 @@
 import logging
 import subprocess
 
-from borgmatic.execute import execute_command
+from borgmatic.execute import BORG_ERROR_EXIT_CODE, execute_command
 
 logger = logging.getLogger(__name__)
 
@@ -44,4 +44,8 @@ def initialize_repository(
     )
 
     # Don't use execute_command() here because it doesn't support interactive prompts.
-    subprocess.check_call(init_command)
+    try:
+        subprocess.check_call(init_command)
+    except subprocess.CalledProcessError as error:
+        if error.returncode >= BORG_ERROR_EXIT_CODE:
+            raise

+ 2 - 1
borgmatic/execute.py

@@ -5,6 +5,7 @@ logger = logging.getLogger(__name__)
 
 
 ERROR_OUTPUT_MAX_LINE_COUNT = 25
+BORG_ERROR_EXIT_CODE = 2
 
 
 def execute_and_log_output(full_command, output_log_level, shell):
@@ -31,7 +32,7 @@ def execute_and_log_output(full_command, output_log_level, shell):
         logger.log(output_log_level, remaining_output)
 
     exit_code = process.poll()
-    if exit_code != 0:
+    if exit_code >= BORG_ERROR_EXIT_CODE:
         # If an error occurs, include its output in the raised exception so that we don't
         # inadvertently hide error output.
         if len(last_lines) == ERROR_OUTPUT_MAX_LINE_COUNT:

+ 1 - 1
setup.py

@@ -1,6 +1,6 @@
 from setuptools import find_packages, setup
 
-VERSION = '1.3.13'
+VERSION = '1.3.14'
 
 
 setup(

+ 12 - 2
tests/integration/test_execute.py

@@ -15,7 +15,16 @@ def test_execute_and_log_output_logs_each_line_separately():
     module.execute_and_log_output(['echo', 'there'], output_log_level=logging.INFO, shell=False)
 
 
+def test_execute_and_log_output_with_borg_warning_does_not_raise():
+    flexmock(module.logger).should_receive('log')
+
+    # Borg's exit code 1 is a warning, not an error.
+    module.execute_and_log_output(['false'], output_log_level=logging.INFO, shell=False)
+
+
 def test_execute_and_log_output_includes_borg_error_output_in_exception():
+    flexmock(module.logger).should_receive('log')
+
     with pytest.raises(subprocess.CalledProcessError) as error:
         module.execute_and_log_output(['grep'], output_log_level=logging.INFO, shell=False)
 
@@ -25,6 +34,7 @@ def test_execute_and_log_output_includes_borg_error_output_in_exception():
 
 def test_execute_and_log_output_truncates_long_borg_error_output():
     flexmock(module).ERROR_OUTPUT_MAX_LINE_COUNT = 0
+    flexmock(module.logger).should_receive('log')
 
     with pytest.raises(subprocess.CalledProcessError) as error:
         module.execute_and_log_output(['grep'], output_log_level=logging.INFO, shell=False)
@@ -40,7 +50,7 @@ def test_execute_and_log_output_with_no_output_logs_nothing():
 
 
 def test_execute_and_log_output_with_error_exit_status_raises():
-    flexmock(module.logger).should_receive('log').never()
+    flexmock(module.logger).should_receive('log')
 
     with pytest.raises(subprocess.CalledProcessError):
-        module.execute_and_log_output(['false'], output_log_level=logging.INFO, shell=False)
+        module.execute_and_log_output(['grep'], output_log_level=logging.INFO, shell=False)

+ 19 - 0
tests/unit/borg/test_init.py

@@ -35,6 +35,25 @@ def test_initialize_repository_calls_borg_with_parameters():
     module.initialize_repository(repository='repo', encryption_mode='repokey')
 
 
+def test_initialize_repository_does_not_raise_for_borg_init_warning():
+    insert_info_command_not_found_mock()
+    flexmock(module.subprocess).should_receive('check_call').and_raise(
+        module.subprocess.CalledProcessError(1, 'borg init')
+    )
+
+    module.initialize_repository(repository='repo', encryption_mode='repokey')
+
+
+def test_initialize_repository_raises_for_borg_init_error():
+    insert_info_command_not_found_mock()
+    flexmock(module.subprocess).should_receive('check_call').and_raise(
+        module.subprocess.CalledProcessError(2, 'borg init')
+    )
+
+    with pytest.raises(subprocess.CalledProcessError):
+        module.initialize_repository(repository='repo', encryption_mode='repokey')
+
+
 def test_initialize_repository_skips_initialization_when_repository_already_exists():
     insert_info_command_found_mock()
     flexmock(module.subprocess).should_receive('check_call').never()