Browse Source

Add test coverage for new code (#793).

Dan Helfman 2 months ago
parent
commit
c0adc4f9df

+ 1 - 1
NEWS

@@ -24,7 +24,7 @@
  * #790: BREAKING: Run all command hooks (both new and deprecated) respecting the
    "working_directory" option if configured, meaning that hook commands are run in that directory.
  * #793: Add configuration options for all verbosity and logging flags, so you don't have to set
-   verbosity on the command-line.
+   them on the command-line.
  * #836: Add a custom command option for the SQLite hook.
  * #837: Add custom command options for the MongoDB hook.
  * #1010: When using Borg 2, don't pass the "--stats" flag to "borg prune".

+ 2 - 1
borgmatic/commands/borgmatic.py

@@ -987,8 +987,9 @@ def get_singular_option_value(configs, option_name):
 
     if len(distinct_values) > 1:
         configure_logging(logging.CRITICAL)
+        joined_values = ', '.join(str(value) for value in distinct_values)
         logger.critical(
-            f'The {option_name} option has conflicting values across configuration files: {", ".join(distinct_values)}'
+            f'The {option_name} option has conflicting values across configuration files: {joined_values}'
         )
         exit_with_help_link()
 

+ 4 - 1
borgmatic/verbosity.py

@@ -40,7 +40,10 @@ def get_verbosity(configs, option_name):
     '''
     try:
         return max(
-            config.get(option_name, DEFAULT_VERBOSITIES[option_name]) for config in configs.values()
+            verbosity
+            for config in configs.values()
+            for verbosity in (config.get(option_name, DEFAULT_VERBOSITIES[option_name]),)
+            if verbosity
         )
     except ValueError:
         return DEFAULT_VERBOSITIES[option_name]

+ 2 - 6
tests/integration/commands/test_arguments.py

@@ -657,17 +657,13 @@ def test_parse_arguments_config_with_subaction_and_required_flags_does_not_raise
 def test_parse_arguments_config_with_subaction_and_global_flags_at_start_does_not_raise():
     flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
 
-    module.parse_arguments(
-        {}, '--dry-run', 'config', 'bootstrap', '--repository', 'repo.borg'
-    )
+    module.parse_arguments({}, '--dry-run', 'config', 'bootstrap', '--repository', 'repo.borg')
 
 
 def test_parse_arguments_config_with_subaction_and_global_flags_at_end_does_not_raise():
     flexmock(module.collect).should_receive('get_default_config_paths').and_return(['default'])
 
-    module.parse_arguments(
-        {}, 'config', 'bootstrap', '--repository', 'repo.borg', '--dry-run'
-    )
+    module.parse_arguments({}, 'config', 'bootstrap', '--repository', 'repo.borg', '--dry-run')
 
 
 def test_parse_arguments_config_with_subaction_and_explicit_config_file_does_not_raise():

+ 3 - 1
tests/unit/borg/test_change_passphrase.py

@@ -111,7 +111,9 @@ def test_change_passphrase_calls_borg_with_umask_flags():
 def test_change_passphrase_calls_borg_with_log_json_flags():
     flexmock(module.flags).should_receive('make_repository_flags').and_return(('repo',))
     config = {'log_json': True}
-    insert_execute_command_mock(('borg', 'key', 'change-passphrase', '--log-json', 'repo'), config=config)
+    insert_execute_command_mock(
+        ('borg', 'key', 'change-passphrase', '--log-json', 'repo'), config=config
+    )
 
     module.change_passphrase(
         repository_path='repo',

+ 58 - 0
tests/unit/commands/test_borgmatic.py

@@ -2217,3 +2217,61 @@ def test_check_and_show_help_on_no_args_with_conflicting_configs():
     flexmock(module.sys).should_receive('exit').never()
 
     module.check_and_show_help_on_no_args(configs)
+
+
+def test_get_singular_option_value_with_conflicting_values_exits():
+    flexmock(module).should_receive('configure_logging')
+    flexmock(module).should_receive('exit_with_help_link').once()
+
+    module.get_singular_option_value(
+        configs={
+            'test1.yaml': {'foo': 1, 'bar': 'baz'},
+            'test2.yaml': {'foo': 2, 'bar': 'baz'},
+        },
+        option_name='foo',
+    )
+
+
+def test_get_singular_option_value_with_same_value_returns_it():
+    flexmock(module).should_receive('configure_logging').never()
+    flexmock(module).should_receive('exit_with_help_link').never()
+
+    assert (
+        module.get_singular_option_value(
+            configs={
+                'test1.yaml': {'foo': 1, 'bar': 'baz'},
+                'test2.yaml': {'foo': 1, 'bar': 'baz'},
+            },
+            option_name='foo',
+        )
+        == 1
+    )
+
+
+def test_get_singular_option_value_with_no_values_returns_none():
+    flexmock(module).should_receive('configure_logging').never()
+    flexmock(module).should_receive('exit_with_help_link').never()
+
+    assert (
+        module.get_singular_option_value(
+            configs={
+                'test1.yaml': {'bar': 'baz'},
+                'test2.yaml': {'bar': 'baz'},
+            },
+            option_name='foo',
+        )
+        is None
+    )
+
+
+def test_get_singular_option_value_with_no_config_returns_none():
+    flexmock(module).should_receive('configure_logging').never()
+    flexmock(module).should_receive('exit_with_help_link').never()
+
+    assert (
+        module.get_singular_option_value(
+            configs={},
+            option_name='foo',
+        )
+        is None
+    )

+ 46 - 0
tests/unit/test_verbosity.py

@@ -1,5 +1,6 @@
 import logging
 
+import pytest
 from flexmock import flexmock
 
 from borgmatic import verbosity as module
@@ -31,3 +32,48 @@ def test_verbosity_to_log_level_maps_unknown_verbosity_to_warning_level():
     flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER
 
     assert module.verbosity_to_log_level('my pants') == logging.WARNING
+
+
+@pytest.mark.parametrize(
+    'option_name',
+    (
+        'verbosity',
+        'syslog_verbosity',
+        'log_file_verbosity',
+        'monitoring_verbosity',
+    ),
+)
+def test_get_verbosity_gets_maximum_verbosity_across_configurations(option_name):
+    assert (
+        module.get_verbosity(
+            configs={
+                'test1.yaml': {option_name: -1},
+                'test2.yaml': {option_name: 2},
+                'test3.yaml': {option_name: None},
+            },
+            option_name=option_name,
+        )
+        == 2
+    )
+
+
+@pytest.mark.parametrize(
+    'option_name',
+    (
+        'verbosity',
+        'syslog_verbosity',
+        'log_file_verbosity',
+        'monitoring_verbosity',
+    ),
+)
+def test_get_verbosity_with_nothing_set_gets_default_verbosity(option_name):
+    assert (
+        module.get_verbosity(
+            configs={
+                'test1.yaml': {},
+                'test2.yaml': {'other': 'thing'},
+            },
+            option_name=option_name,
+        )
+        == module.DEFAULT_VERBOSITIES[option_name]
+    )