From 775385e688e87390f6cf052ebfa23e644ffe02ba Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Sun, 9 Feb 2025 22:44:38 -0800 Subject: [PATCH] Get unit tests passing again (#966). --- borgmatic/borg/environment.py | 2 +- borgmatic/config/schema.yaml | 3 +- borgmatic/hooks/data_source/mariadb.py | 6 +- borgmatic/hooks/data_source/mongodb.py | 4 +- borgmatic/hooks/data_source/mysql.py | 6 +- borgmatic/hooks/monitoring/pagerduty.py | 2 +- tests/integration/config/test_validate.py | 30 ---- tests/unit/borg/test_environment.py | 4 + tests/unit/borg/test_passcommand.py | 21 +++ tests/unit/commands/test_borgmatic.py | 13 +- tests/unit/config/test_credential.py | 135 ------------------ tests/unit/hooks/credential/test_tag.py | 51 +++++++ tests/unit/hooks/data_source/test_mariadb.py | 66 +++++++++ tests/unit/hooks/data_source/test_mongodb.py | 36 +++++ tests/unit/hooks/data_source/test_mysql.py | 60 ++++++++ .../unit/hooks/data_source/test_postgresql.py | 90 ++++++++++++ tests/unit/hooks/monitoring/test_ntfy.py | 42 ++++++ tests/unit/hooks/monitoring/test_pagerduty.py | 18 +++ tests/unit/hooks/monitoring/test_pushover.py | 46 +++++- tests/unit/hooks/monitoring/test_zabbix.py | 84 +++++++++-- 20 files changed, 512 insertions(+), 207 deletions(-) delete mode 100644 tests/unit/config/test_credential.py create mode 100644 tests/unit/hooks/credential/test_tag.py diff --git a/borgmatic/borg/environment.py b/borgmatic/borg/environment.py index c58dcdbf..85033309 100644 --- a/borgmatic/borg/environment.py +++ b/borgmatic/borg/environment.py @@ -40,7 +40,7 @@ def make_environment(config): for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items(): value = config.get(option_name) - if option_name in CREDENTIAL_OPTIONS: + if option_name in CREDENTIAL_OPTIONS and value is not None: value = borgmatic.hooks.credential.tag.resolve_credential(value) if value is not None: diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index 5fee3890..7c8e5b0a 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -1646,7 +1646,8 @@ properties: token: type: string description: | - Your application's API token. Supports the "!credential" tag. + Your application's API token. Supports the "!credential" + tag. example: 7ms6TXHpTokTou2P6x4SodDeentHRa user: type: string diff --git a/borgmatic/hooks/data_source/mariadb.py b/borgmatic/hooks/data_source/mariadb.py index fb072a31..dcdd431f 100644 --- a/borgmatic/hooks/data_source/mariadb.py +++ b/borgmatic/hooks/data_source/mariadb.py @@ -289,11 +289,7 @@ def restore_data_source_dump( + (('--protocol', 'tcp') if hostname or port else ()) + (('--user', username) if username else ()) ) - extra_environment = ( - {'MYSQL_PWD': borgmatic.hooks.credential.tag.resolve_credential(password)} - if password - else None - ) + extra_environment = {'MYSQL_PWD': password} if password else None logger.debug(f"Restoring MariaDB database {data_source['name']}{dry_run_label}") if dry_run: diff --git a/borgmatic/hooks/data_source/mongodb.py b/borgmatic/hooks/data_source/mongodb.py index 098a2aa4..55dc6e9c 100644 --- a/borgmatic/hooks/data_source/mongodb.py +++ b/borgmatic/hooks/data_source/mongodb.py @@ -236,9 +236,9 @@ def build_restore_command(extract_process, database, dump_filename, connection_p if port: command.extend(('--port', str(port))) if username: - command.extend(('--username', borgmatic.hooks.credential.tag.resolve_credential(username))) + command.extend(('--username', username)) if password: - command.extend(('--password', borgmatic.hooks.credential.tag.resolve_credential(password))) + command.extend(('--password', password)) if 'authentication_database' in database: command.extend(('--authenticationDatabase', database['authentication_database'])) if 'restore_options' in database: diff --git a/borgmatic/hooks/data_source/mysql.py b/borgmatic/hooks/data_source/mysql.py index 00863c90..5be8b71e 100644 --- a/borgmatic/hooks/data_source/mysql.py +++ b/borgmatic/hooks/data_source/mysql.py @@ -288,11 +288,7 @@ def restore_data_source_dump( + (('--protocol', 'tcp') if hostname or port else ()) + (('--user', username) if username else ()) ) - extra_environment = ( - {'MYSQL_PWD': borgmatic.hooks.credential.tag.resolve_credential(password)} - if password - else None - ) + extra_environment = {'MYSQL_PWD': password} if password else None logger.debug(f"Restoring MySQL database {data_source['name']}{dry_run_label}") if dry_run: diff --git a/borgmatic/hooks/monitoring/pagerduty.py b/borgmatic/hooks/monitoring/pagerduty.py index 0edc4d96..53839eff 100644 --- a/borgmatic/hooks/monitoring/pagerduty.py +++ b/borgmatic/hooks/monitoring/pagerduty.py @@ -41,7 +41,7 @@ def ping_monitor(hook_config, config, config_filename, state, monitoring_log_lev return try: - inegration_key = borgmatic.hooks.credential.tag.resolve_credential( + integration_key = borgmatic.hooks.credential.tag.resolve_credential( hook_config.get('integration_key') ) except ValueError as error: diff --git a/tests/integration/config/test_validate.py b/tests/integration/config/test_validate.py index e5138d32..9cd5c980 100644 --- a/tests/integration/config/test_validate.py +++ b/tests/integration/config/test_validate.py @@ -283,33 +283,3 @@ def test_parse_configuration_applies_normalization_after_environment_variable_in } assert config_paths == {'/tmp/config.yaml'} assert logs - - -def test_parse_configuration_interpolates_credentials(): - mock_config_and_schema( - ''' - source_directories: - - /home - - repositories: - - path: hostname.borg - - encryption_passphrase: !credential systemd mycredential - ''' - ) - flexmock(os.environ).should_receive('get').replace_with(lambda variable_name: '/var') - credential_stream = io.StringIO('password') - credential_stream.name = '/var/mycredential' - builtins = flexmock(sys.modules['builtins']) - builtins.should_receive('open').with_args('/var/mycredential').and_return(credential_stream) - - config, config_paths, logs = module.parse_configuration('/tmp/config.yaml', '/tmp/schema.yaml') - - assert config == { - 'source_directories': ['/home'], - 'repositories': [{'path': 'hostname.borg'}], - 'encryption_passphrase': 'password', - 'bootstrap': {}, - } - assert config_paths == {'/tmp/config.yaml'} - assert logs == [] diff --git a/tests/unit/borg/test_environment.py b/tests/unit/borg/test_environment.py index e007664e..fda097b7 100644 --- a/tests/unit/borg/test_environment.py +++ b/tests/unit/borg/test_environment.py @@ -24,6 +24,10 @@ def test_make_environment_with_passphrase_should_set_environment(): ).and_return(None) flexmock(module.os).should_receive('pipe').never() flexmock(module.os.environ).should_receive('get').and_return(None) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) + environment = module.make_environment({'encryption_passphrase': 'pass'}) assert environment.get('BORG_PASSPHRASE') == 'pass' diff --git a/tests/unit/borg/test_passcommand.py b/tests/unit/borg/test_passcommand.py index 198cfd15..1a9a0e97 100644 --- a/tests/unit/borg/test_passcommand.py +++ b/tests/unit/borg/test_passcommand.py @@ -4,6 +4,7 @@ from borgmatic.borg import passcommand as module def test_run_passcommand_with_passphrase_configured_bails(): + module.run_passcommand.cache_clear() flexmock(module.borgmatic.execute).should_receive('execute_command_and_capture_output').never() assert ( @@ -13,6 +14,7 @@ def test_run_passcommand_with_passphrase_configured_bails(): def test_run_passcommand_without_passphrase_configured_executes_passcommand(): + module.run_passcommand.cache_clear() flexmock(module.borgmatic.execute).should_receive( 'execute_command_and_capture_output' ).and_return('passphrase').once() @@ -24,6 +26,7 @@ def test_run_passcommand_without_passphrase_configured_executes_passcommand(): def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): + module.run_passcommand.cache_clear() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working' ) @@ -40,6 +43,7 @@ def test_get_passphrase_from_passcommand_with_configured_passcommand_runs_it(): def test_get_passphrase_from_passcommand_with_configured_passphrase_and_passcommand_detects_passphrase(): + module.run_passcommand.cache_clear() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working' ) @@ -56,6 +60,7 @@ def test_get_passphrase_from_passcommand_with_configured_passphrase_and_passcomm def test_get_passphrase_from_passcommand_with_configured_blank_passphrase_and_passcommand_detects_passphrase(): + module.run_passcommand.cache_clear() flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( '/working' ) @@ -69,3 +74,19 @@ def test_get_passphrase_from_passcommand_with_configured_blank_passphrase_and_pa ) is None ) + + +def test_run_passcommand_caches_passcommand_after_first_call(): + module.run_passcommand.cache_clear() + flexmock(module.borgmatic.execute).should_receive( + 'execute_command_and_capture_output' + ).and_return('passphrase').once() + + assert ( + module.run_passcommand('passcommand', passphrase_configured=False, working_directory=None) + == 'passphrase' + ) + assert ( + module.run_passcommand('passcommand', passphrase_configured=False, working_directory=None) + == 'passphrase' + ) diff --git a/tests/unit/commands/test_borgmatic.py b/tests/unit/commands/test_borgmatic.py index ce109565..1615dcf4 100644 --- a/tests/unit/commands/test_borgmatic.py +++ b/tests/unit/commands/test_borgmatic.py @@ -1115,16 +1115,10 @@ def test_run_actions_runs_multiple_actions_in_argument_order(): @pytest.mark.parametrize( - 'resolve_env,resolve_credentials', - ( - (True, True), - (False, True), - (True, False), - ), + 'resolve_env', + ((True, False),), ) -def test_load_configurations_collects_parsed_configurations_and_logs( - resolve_env, resolve_credentials -): +def test_load_configurations_collects_parsed_configurations_and_logs(resolve_env): configuration = flexmock() other_configuration = flexmock() test_expected_logs = [flexmock(), flexmock()] @@ -1137,7 +1131,6 @@ def test_load_configurations_collects_parsed_configurations_and_logs( module.load_configurations( ('test.yaml', 'other.yaml'), resolve_env=resolve_env, - resolve_credentials=resolve_credentials, ) ) diff --git a/tests/unit/config/test_credential.py b/tests/unit/config/test_credential.py deleted file mode 100644 index f6e16b20..00000000 --- a/tests/unit/config/test_credential.py +++ /dev/null @@ -1,135 +0,0 @@ -import pytest -from flexmock import flexmock - -from borgmatic.config import credential as module - - -def test_resolve_credentials_passes_through_string_without_credential_tag(): - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() - - assert ( - module.resolve_credentials(config=flexmock(), item='!no credentials here') - == '!no credentials here' - ) - - -def test_resolve_credentials_passes_through_none(): - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() - - assert module.resolve_credentials(config=flexmock(), item=None) is None - - -def test_resolve_credentials_with_invalid_credential_tag_raises(): - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() - - with pytest.raises(ValueError): - module.resolve_credentials(config=flexmock(), item='!credential systemd') - - -def test_resolve_credentials_with_valid_credential_tag_loads_credential(): - config = flexmock() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'mycredential', - ).and_return('result').once() - - assert ( - module.resolve_credentials(config=config, item='!credential systemd mycredential') - == 'result' - ) - - -def test_resolve_credentials_with_list_recurses_and_loads_credentials(): - config = flexmock() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'mycredential', - ).and_return('result1').once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'othercredential', - ).and_return('result2').once() - - assert module.resolve_credentials( - config=config, - item=['!credential systemd mycredential', 'nope', '!credential systemd othercredential'], - ) == ['result1', 'nope', 'result2'] - - -def test_resolve_credentials_with_dict_recurses_and_loads_credentials(): - config = flexmock() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'mycredential', - ).and_return('result1').once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'othercredential', - ).and_return('result2').once() - - assert module.resolve_credentials( - config=config, - item={ - 'a': '!credential systemd mycredential', - 'b': 'nope', - 'c': '!credential systemd othercredential', - }, - ) == {'a': 'result1', 'b': 'nope', 'c': 'result2'} - - -def test_resolve_credentials_with_list_of_dicts_recurses_and_loads_credentials(): - config = flexmock() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'mycredential', - ).and_return('result1').once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'othercredential', - ).and_return('result2').once() - - assert module.resolve_credentials( - config=config, - item=[ - {'a': '!credential systemd mycredential', 'b': 'nope'}, - {'c': '!credential systemd othercredential'}, - ], - ) == [{'a': 'result1', 'b': 'nope'}, {'c': 'result2'}] - - -def test_resolve_credentials_with_dict_of_lists_recurses_and_loads_credentials(): - config = flexmock() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'mycredential', - ).and_return('result1').once() - flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( - 'load_credential', - config, - 'systemd', - 'othercredential', - ).and_return('result2').once() - - assert module.resolve_credentials( - config=config, - item={ - 'a': ['!credential systemd mycredential', 'nope'], - 'b': ['!credential systemd othercredential'], - }, - ) == {'a': ['result1', 'nope'], 'b': ['result2']} diff --git a/tests/unit/hooks/credential/test_tag.py b/tests/unit/hooks/credential/test_tag.py new file mode 100644 index 00000000..d802ce69 --- /dev/null +++ b/tests/unit/hooks/credential/test_tag.py @@ -0,0 +1,51 @@ +import pytest +from flexmock import flexmock + +from borgmatic.hooks.credential import tag as module + + +def test_resolve_credential_passes_through_string_without_credential_tag(): + module.resolve_credential.cache_clear() + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() + + assert module.resolve_credential('!no credentials here') == '!no credentials here' + + +def test_resolve_credential_passes_through_none(): + module.resolve_credential.cache_clear() + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() + + assert module.resolve_credential(None) is None + + +def test_resolve_credential_with_invalid_credential_tag_raises(): + module.resolve_credential.cache_clear() + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').never() + + with pytest.raises(ValueError): + module.resolve_credential('!credential systemd') + + +def test_resolve_credential_with_valid_credential_tag_loads_credential(): + module.resolve_credential.cache_clear() + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( + 'load_credential', + {}, + 'systemd', + 'mycredential', + ).and_return('result').once() + + assert module.resolve_credential('!credential systemd mycredential') == 'result' + + +def test_resolve_credential_caches_credential_after_first_call(): + module.resolve_credential.cache_clear() + flexmock(module.borgmatic.hooks.dispatch).should_receive('call_hook').with_args( + 'load_credential', + {}, + 'systemd', + 'mycredential', + ).and_return('result').once() + + assert module.resolve_credential('!credential systemd mycredential') == 'result' + assert module.resolve_credential('!credential systemd mycredential') == 'result' diff --git a/tests/unit/hooks/data_source/test_mariadb.py b/tests/unit/hooks/data_source/test_mariadb.py index e21979d6..f354e8d8 100644 --- a/tests/unit/hooks/data_source/test_mariadb.py +++ b/tests/unit/hooks/data_source/test_mariadb.py @@ -25,6 +25,9 @@ def test_database_names_to_dump_bails_for_dry_run(): def test_database_names_to_dump_queries_mariadb_for_database_names(): extra_environment = flexmock() + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('mariadb', '--skip-column-names', '--batch', '--execute', 'show schemas'), extra_environment=extra_environment, @@ -50,6 +53,9 @@ def test_dump_data_sources_dumps_each_database(): databases = [{'name': 'foo'}, {'name': 'bar'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) ) @@ -81,6 +87,9 @@ def test_dump_data_sources_dumps_with_password(): database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'} process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) ) @@ -108,6 +117,9 @@ def test_dump_data_sources_dumps_all_databases_at_once(): databases = [{'name': 'all'}] process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) flexmock(module).should_receive('execute_dump_command').with_args( database={'name': 'all'}, @@ -132,6 +144,9 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured databases = [{'name': 'all', 'format': 'sql'}] processes = [flexmock(), flexmock()] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar')) for name, process in zip(('foo', 'bar'), processes): @@ -199,6 +214,9 @@ def test_execute_dump_command_runs_mariadb_dump(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -231,6 +249,9 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -262,6 +283,9 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -300,6 +324,9 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -334,6 +361,9 @@ def test_execute_dump_command_runs_mariadb_dump_with_options(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -367,6 +397,9 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -422,6 +455,9 @@ def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump(): def test_execute_dump_command_with_dry_run_skips_mariadb_dump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').never() @@ -442,6 +478,9 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump(): def test_dump_data_sources_errors_for_missing_all_databases(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( 'databases/localhost/all' ) @@ -461,6 +500,9 @@ def test_dump_data_sources_errors_for_missing_all_databases(): def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( 'databases/localhost/all' ) @@ -483,6 +525,9 @@ def test_restore_data_source_dump_runs_mariadb_to_restore(): hook_config = [{'name': 'foo'}, {'name': 'bar'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch'), processes=[extract_process], @@ -511,6 +556,9 @@ def test_restore_data_source_dump_runs_mariadb_with_options(): hook_config = [{'name': 'foo', 'restore_options': '--harder'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch', '--harder'), processes=[extract_process], @@ -541,6 +589,9 @@ def test_restore_data_source_dump_runs_non_default_mariadb_with_options(): ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('custom_mariadb', '--batch', '--harder'), processes=[extract_process], @@ -569,6 +620,9 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port(): hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -606,6 +660,9 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password(): hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mariadb', '--batch', '--user', 'root'), processes=[extract_process], @@ -644,6 +701,9 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -695,6 +755,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mariadb', @@ -733,6 +796,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo'}] + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').never() module.restore_data_source_dump( diff --git a/tests/unit/hooks/data_source/test_mongodb.py b/tests/unit/hooks/data_source/test_mongodb.py index 1d2c0c7b..1bc17e9a 100644 --- a/tests/unit/hooks/data_source/test_mongodb.py +++ b/tests/unit/hooks/data_source/test_mongodb.py @@ -124,6 +124,9 @@ def test_dump_data_sources_runs_mongodump_with_username_and_password(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( 'databases/localhost/foo' ) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -242,6 +245,9 @@ def test_dump_data_sources_runs_mongodumpall_for_all_databases(): def test_build_dump_command_with_username_injection_attack_gets_escaped(): database = {'name': 'test', 'username': 'bob; naughty-command'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) command = module.build_dump_command(database, dump_filename='test', dump_format='archive') @@ -254,6 +260,9 @@ def test_restore_data_source_dump_runs_mongorestore(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive', '--drop'], processes=[extract_process], @@ -285,6 +294,9 @@ def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ 'mongorestore', @@ -330,6 +342,9 @@ def test_restore_data_source_dump_runs_mongorestore_with_username_and_password() flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ 'mongorestore', @@ -381,6 +396,9 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ 'mongorestore', @@ -436,6 +454,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ 'mongorestore', @@ -479,6 +500,9 @@ def test_restore_data_source_dump_runs_mongorestore_with_options(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive', '--drop', '--harder'], processes=[extract_process], @@ -508,6 +532,9 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( [ 'mongorestore', @@ -545,6 +572,9 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--archive'], processes=[extract_process], @@ -573,6 +603,9 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').never() module.restore_data_source_dump( @@ -596,6 +629,9 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ['mongorestore', '--dir', '/dump/path', '--drop'], processes=[], diff --git a/tests/unit/hooks/data_source/test_mysql.py b/tests/unit/hooks/data_source/test_mysql.py index 5eb46e35..e81182c7 100644 --- a/tests/unit/hooks/data_source/test_mysql.py +++ b/tests/unit/hooks/data_source/test_mysql.py @@ -16,6 +16,9 @@ def test_database_names_to_dump_passes_through_name(): def test_database_names_to_dump_bails_for_dry_run(): extra_environment = flexmock() + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').never() names = module.database_names_to_dump({'name': 'all'}, extra_environment, dry_run=True) @@ -25,6 +28,9 @@ def test_database_names_to_dump_bails_for_dry_run(): def test_database_names_to_dump_queries_mysql_for_database_names(): extra_environment = flexmock() + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('mysql', '--skip-column-names', '--batch', '--execute', 'show schemas'), extra_environment=extra_environment, @@ -81,6 +87,9 @@ def test_dump_data_sources_dumps_with_password(): database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'} process = flexmock() flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return( ('bar',) ) @@ -199,6 +208,9 @@ def test_execute_dump_command_runs_mysqldump(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -231,6 +243,9 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -262,6 +277,9 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -300,6 +318,9 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -334,6 +355,9 @@ def test_execute_dump_command_runs_mysqldump_with_options(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -367,6 +391,9 @@ def test_execute_dump_command_runs_non_default_mysqldump(): process = flexmock() flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -420,6 +447,9 @@ def test_execute_dump_command_with_duplicate_dump_skips_mysqldump(): def test_execute_dump_command_with_dry_run_skips_mysqldump(): flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').never() @@ -440,6 +470,9 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump(): def test_dump_data_sources_errors_for_missing_all_databases(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( 'databases/localhost/all' ) @@ -459,6 +492,9 @@ def test_dump_data_sources_errors_for_missing_all_databases(): def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run(): databases = [{'name': 'all'}] flexmock(module).should_receive('make_dump_path').and_return('') + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return( 'databases/localhost/all' ) @@ -481,6 +517,9 @@ def test_restore_data_source_dump_runs_mysql_to_restore(): hook_config = [{'name': 'foo'}, {'name': 'bar'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch'), processes=[extract_process], @@ -509,6 +548,9 @@ def test_restore_data_source_dump_runs_mysql_with_options(): hook_config = [{'name': 'foo', 'restore_options': '--harder'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch', '--harder'), processes=[extract_process], @@ -537,6 +579,9 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options(): hook_config = [{'name': 'foo', 'mysql_command': 'custom_mysql', 'restore_options': '--harder'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('custom_mysql', '--batch', '--harder'), processes=[extract_process], @@ -565,6 +610,9 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port(): hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -602,6 +650,9 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password(): hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ('mysql', '--batch', '--user', 'root'), processes=[extract_process], @@ -640,6 +691,9 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -691,6 +745,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').with_args( ( 'mysql', @@ -729,6 +786,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo'}] + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_with_processes').never() module.restore_data_source_dump( diff --git a/tests/unit/hooks/data_source/test_postgresql.py b/tests/unit/hooks/data_source/test_postgresql.py index 845859f7..05f3f7dd 100644 --- a/tests/unit/hooks/data_source/test_postgresql.py +++ b/tests/unit/hooks/data_source/test_postgresql.py @@ -24,6 +24,9 @@ def test_make_extra_environment_maps_options_to_environment(): 'PGSSLROOTCERT': 'root.crt', 'PGSSLCRL': 'crl.crl', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) extra_env = module.make_extra_environment(database) @@ -32,6 +35,9 @@ def test_make_extra_environment_maps_options_to_environment(): def test_make_extra_environment_with_cli_password_sets_correct_password(): database = {'name': 'foo', 'restore_password': 'trustsome1', 'password': 'anotherpassword'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) extra = module.make_extra_environment( database, restore_connection_params={'password': 'clipassword'} @@ -78,6 +84,9 @@ def test_database_names_to_dump_passes_through_all_without_format(): def test_database_names_to_dump_with_all_and_format_and_dry_run_bails(): database = {'name': 'all', 'format': 'custom'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').never() assert module.database_names_to_dump(database, flexmock(), dry_run=True) == () @@ -85,6 +94,9 @@ def test_database_names_to_dump_with_all_and_format_and_dry_run_bails(): def test_database_names_to_dump_with_all_and_format_lists_databases(): database = {'name': 'all', 'format': 'custom'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').and_return( 'foo,test,\nbar,test,"stuff and such"' ) @@ -97,6 +109,9 @@ def test_database_names_to_dump_with_all_and_format_lists_databases(): def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostname_and_port(): database = {'name': 'all', 'format': 'custom', 'hostname': 'localhost', 'port': 1234} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( 'psql', @@ -121,6 +136,9 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostnam def test_database_names_to_dump_with_all_and_format_lists_databases_with_username(): database = {'name': 'all', 'format': 'custom', 'username': 'postgres'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( 'psql', @@ -143,6 +161,9 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam def test_database_names_to_dump_with_all_and_format_lists_databases_with_options(): database = {'name': 'all', 'format': 'custom', 'list_options': '--harder'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ('psql', '--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only', '--harder'), extra_environment=object, @@ -156,6 +177,9 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_options def test_database_names_to_dump_with_all_and_format_excludes_particular_databases(): database = {'name': 'all', 'format': 'custom'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').and_return( 'foo,test,\ntemplate0,test,blah' ) @@ -169,6 +193,9 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command(): 'format': 'custom', 'psql_command': 'docker exec --workdir * mycontainer psql', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('execute_command_and_capture_output').with_args( ( 'docker', @@ -219,6 +246,9 @@ def test_dump_data_sources_runs_pg_dump_for_each_database(): 'databases/localhost/foo' ).and_return('databases/localhost/bar') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') for name, process in zip(('foo', 'bar'), processes): @@ -323,6 +353,9 @@ def test_dump_data_sources_with_dry_run_skips_pg_dump(): 'databases/localhost/foo' ).and_return('databases/localhost/bar') flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() flexmock(module).should_receive('execute_command').never() @@ -349,6 +382,9 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port(): 'databases/database.example.org/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -394,6 +430,9 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password(): 'databases/localhost/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -437,6 +476,9 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped(): 'databases/localhost/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -477,6 +519,9 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format(): 'databases/localhost/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_parent_directory_for_dump') flexmock(module.dump).should_receive('create_named_pipe_for_dump').never() @@ -519,6 +564,9 @@ def test_dump_data_sources_runs_pg_dump_with_options(): 'databases/localhost/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -559,6 +607,9 @@ def test_dump_data_sources_runs_pg_dumpall_for_all_databases(): 'databases/localhost/all' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -588,6 +639,9 @@ def test_dump_data_sources_runs_non_default_pg_dump(): 'databases/localhost/foo' ) flexmock(module.os.path).should_receive('exists').and_return(False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.dump).should_receive('create_named_pipe_for_dump') flexmock(module).should_receive('execute_command').with_args( @@ -623,6 +677,9 @@ def test_restore_data_source_dump_runs_pg_restore(): hook_config = [{'name': 'foo', 'schemas': None}, {'name': 'bar'}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -677,6 +734,9 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port(): ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -739,6 +799,9 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password(): ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return( {'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'} ) @@ -810,6 +873,9 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return( {'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'} ) @@ -889,6 +955,9 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_ ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return( {'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'} ) @@ -962,6 +1031,9 @@ def test_restore_data_source_dump_runs_pg_restore_with_options(): ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1016,6 +1088,9 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump(): hook_config = [{'name': 'all', 'schemas': None}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1055,6 +1130,9 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump(): hook_config = [{'name': 'foo', 'format': 'plain', 'schemas': None}] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1106,6 +1184,9 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): ] extract_process = flexmock(stdout=flexmock()) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1167,6 +1248,9 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql(): def test_restore_data_source_dump_with_dry_run_skips_restore(): hook_config = [{'name': 'foo', 'schemas': None}] + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename') @@ -1191,6 +1275,9 @@ def test_restore_data_source_dump_with_dry_run_skips_restore(): def test_restore_data_source_dump_without_extract_process_restores_from_disk(): hook_config = [{'name': 'foo', 'schemas': None}] + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') @@ -1243,6 +1330,9 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk(): def test_restore_data_source_dump_with_schemas_restores_schemas(): hook_config = [{'name': 'foo', 'schemas': ['bar', 'baz']}] + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module).should_receive('make_extra_environment').and_return({'PGSSLMODE': 'disable'}) flexmock(module).should_receive('make_dump_path') flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path') diff --git a/tests/unit/hooks/monitoring/test_ntfy.py b/tests/unit/hooks/monitoring/test_ntfy.py index a5819ec9..efbecf96 100644 --- a/tests/unit/hooks/monitoring/test_ntfy.py +++ b/tests/unit/hooks/monitoring/test_ntfy.py @@ -36,6 +36,9 @@ def return_default_message_headers(state=Enum): def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -57,6 +60,9 @@ def test_ping_monitor_with_access_token_hits_hosted_ntfy_on_fail(): 'topic': topic, 'access_token': 'abc123', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -80,6 +86,9 @@ def test_ping_monitor_with_username_password_and_access_token_ignores_username_p 'password': 'fakepassword', 'access_token': 'abc123', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -103,6 +112,9 @@ def test_ping_monitor_with_username_password_hits_hosted_ntfy_on_fail(): 'username': 'testuser', 'password': 'fakepassword', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -121,6 +133,9 @@ def test_ping_monitor_with_username_password_hits_hosted_ntfy_on_fail(): def test_ping_monitor_with_password_but_no_username_warns(): hook_config = {'topic': topic, 'password': 'fakepassword'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -140,6 +155,9 @@ def test_ping_monitor_with_password_but_no_username_warns(): def test_ping_monitor_with_username_but_no_password_warns(): hook_config = {'topic': topic, 'username': 'testuser'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -159,6 +177,9 @@ def test_ping_monitor_with_username_but_no_password_warns(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -173,6 +194,9 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -187,6 +211,9 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish(): def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail(): hook_config = {'topic': topic, 'server': custom_base_url} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{custom_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -205,6 +232,9 @@ def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail(): def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -219,6 +249,9 @@ def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run(): def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail(): hook_config = {'topic': topic, 'fail': custom_message_config} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=custom_message_headers, auth=None ).and_return(flexmock(ok=True)).once() @@ -235,6 +268,9 @@ def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail(): def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start(): hook_config = {'topic': topic, 'states': ['start', 'fail']} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.START), @@ -253,6 +289,9 @@ def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start(): def test_ping_monitor_with_connection_error_logs_warning(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{default_base_url}/{topic}', headers=return_default_message_headers(borgmatic.hooks.monitoring.monitor.State.FAIL), @@ -272,6 +311,9 @@ def test_ping_monitor_with_connection_error_logs_warning(): def test_ping_monitor_with_other_error_logs_warning(): hook_config = {'topic': topic} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) response = flexmock(ok=False) response.should_receive('raise_for_status').and_raise( module.requests.exceptions.RequestException diff --git a/tests/unit/hooks/monitoring/test_pagerduty.py b/tests/unit/hooks/monitoring/test_pagerduty.py index bf7cc7ba..8da27eb3 100644 --- a/tests/unit/hooks/monitoring/test_pagerduty.py +++ b/tests/unit/hooks/monitoring/test_pagerduty.py @@ -4,6 +4,9 @@ from borgmatic.hooks.monitoring import pagerduty as module def test_ping_monitor_ignores_start_state(): + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -17,6 +20,9 @@ def test_ping_monitor_ignores_start_state(): def test_ping_monitor_ignores_finish_state(): + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -30,6 +36,9 @@ def test_ping_monitor_ignores_finish_state(): def test_ping_monitor_calls_api_for_fail_state(): + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)) module.ping_monitor( @@ -43,6 +52,9 @@ def test_ping_monitor_calls_api_for_fail_state(): def test_ping_monitor_dry_run_does_not_call_api(): + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').never() module.ping_monitor( @@ -56,6 +68,9 @@ def test_ping_monitor_dry_run_does_not_call_api(): def test_ping_monitor_with_connection_error_logs_warning(): + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').and_raise( module.requests.exceptions.ConnectionError ) @@ -73,6 +88,9 @@ def test_ping_monitor_with_connection_error_logs_warning(): def test_ping_monitor_with_other_error_logs_warning(): response = flexmock(ok=False) + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) response.should_receive('raise_for_status').and_raise( module.requests.exceptions.RequestException ) diff --git a/tests/unit/hooks/monitoring/test_pushover.py b/tests/unit/hooks/monitoring/test_pushover.py index 281a88f0..ea835ae3 100644 --- a/tests/unit/hooks/monitoring/test_pushover.py +++ b/tests/unit/hooks/monitoring/test_pushover.py @@ -11,6 +11,9 @@ def test_ping_monitor_config_with_minimum_config_fail_state_backup_successfully_ should be auto populated with the default value which is the state name. ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -38,6 +41,9 @@ def test_ping_monitor_config_with_minimum_config_start_state_backup_not_send_to_ 'start' state. Only the 'fail' state is enabled by default. ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').never() @@ -63,6 +69,9 @@ def test_ping_monitor_start_state_backup_default_message_successfully_send_to_pu 'user': '983hfe0of902lkjfa2amanfgui', 'states': {'start', 'fail', 'finish'}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -96,6 +105,9 @@ def test_ping_monitor_start_state_backup_custom_message_successfully_send_to_pus 'states': {'start', 'fail', 'finish'}, 'start': {'message': 'custom start message'}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -128,6 +140,9 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'states': {'start', 'fail', 'finish'}, 'start': {'priority': 2}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -163,6 +178,9 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'states': {'start', 'fail', 'finish'}, 'start': {'priority': 2, 'expire': 600}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -198,6 +216,9 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_emergency 'states': {'start', 'fail', 'finish'}, 'start': {'priority': 2, 'retry': 30}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -236,6 +257,9 @@ def test_ping_monitor_start_state_backup_default_message_with_priority_high_decl 'start': {'priority': 1, 'expire': 30, 'retry': 30}, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').never() @@ -288,6 +312,9 @@ def test_ping_monitor_start_state_backup_based_on_documentation_advanced_example 'url_title': 'Login to ticketing system', }, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -351,6 +378,9 @@ def test_ping_monitor_fail_state_backup_based_on_documentation_advanced_example_ 'url_title': 'Login to ticketing system', }, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -419,6 +449,9 @@ def test_ping_monitor_finish_state_backup_based_on_documentation_advanced_exampl 'url_title': 'Login to ticketing system', }, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').with_args( 'https://api.pushover.net/1/messages.json', @@ -446,12 +479,15 @@ def test_ping_monitor_finish_state_backup_based_on_documentation_advanced_exampl ) -def test_ping_monitor_config_with_minimum_config_fail_state_backup_successfully_send_to_pushover_dryrun(): +def test_ping_monitor_config_with_minimum_config_fail_state_backup_successfully_send_to_pushover_dry_run(): ''' This test should be the minimum working configuration. The "message" should be auto populated with the default value which is the state name. ''' hook_config = {'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui'} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)).never() @@ -473,6 +509,9 @@ def test_ping_monitor_config_incorrect_state_exit_early(): 'token': 'ksdjfwoweijfvwoeifvjmwghagy92', 'user': '983hfe0of902lkjfa2amanfgui', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').never() flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True)).never() @@ -486,7 +525,7 @@ def test_ping_monitor_config_incorrect_state_exit_early(): ) -def test_ping_monitor_push_post_error_exits_early(): +def test_ping_monitor_push_post_error_bails(): ''' This test simulates the Pushover servers not responding with a 200 OK. We should raise for status and warn then exit. @@ -496,6 +535,9 @@ def test_ping_monitor_push_post_error_exits_early(): 'user': '983hfe0of902lkjfa2amanfgui', } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) push_response = flexmock(ok=False) push_response.should_receive('raise_for_status').and_raise( module.requests.ConnectionError diff --git a/tests/unit/hooks/monitoring/test_zabbix.py b/tests/unit/hooks/monitoring/test_zabbix.py index 77193d67..057b4193 100644 --- a/tests/unit/hooks/monitoring/test_zabbix.py +++ b/tests/unit/hooks/monitoring/test_zabbix.py @@ -57,7 +57,7 @@ AUTH_HEADERS_API_KEY = { AUTH_HEADERS_USERNAME_PASSWORD = {'Content-Type': 'application/json-rpc'} -def test_ping_monitor_with_non_matching_state_exits_early(): +def test_ping_monitor_with_non_matching_state_bails(): hook_config = {'api_key': API_KEY} flexmock(module.requests).should_receive('post').never() @@ -71,10 +71,13 @@ def test_ping_monitor_with_non_matching_state_exits_early(): ) -def test_ping_monitor_config_with_api_key_only_exit_early(): +def test_ping_monitor_config_with_api_key_only_bails(): # This test should exit early since only providing an API KEY is not enough # for the hook to work hook_config = {'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -88,10 +91,13 @@ def test_ping_monitor_config_with_api_key_only_exit_early(): ) -def test_ping_monitor_config_with_host_only_exit_early(): +def test_ping_monitor_config_with_host_only_bails(): # This test should exit early since only providing a HOST is not enough # for the hook to work hook_config = {'host': HOST} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -105,10 +111,13 @@ def test_ping_monitor_config_with_host_only_exit_early(): ) -def test_ping_monitor_config_with_key_only_exit_early(): +def test_ping_monitor_config_with_key_only_bails(): # This test should exit early since only providing a KEY is not enough # for the hook to work hook_config = {'key': KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -122,10 +131,13 @@ def test_ping_monitor_config_with_key_only_exit_early(): ) -def test_ping_monitor_config_with_server_only_exit_early(): +def test_ping_monitor_config_with_server_only_bails(): # This test should exit early since only providing a SERVER is not enough # for the hook to work hook_config = {'server': SERVER} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -139,9 +151,12 @@ def test_ping_monitor_config_with_server_only_exit_early(): ) -def test_ping_monitor_config_user_password_no_zabbix_data_exit_early(): +def test_ping_monitor_config_user_password_no_zabbix_data_bails(): # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to hook_config = {'server': SERVER, 'username': USERNAME, 'password': PASSWORD} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -155,9 +170,12 @@ def test_ping_monitor_config_user_password_no_zabbix_data_exit_early(): ) -def test_ping_monitor_config_api_key_no_zabbix_data_exit_early(): +def test_ping_monitor_config_api_key_no_zabbix_data_bails(): # This test should exit early since there are HOST/KEY or ITEMID provided to publish data to hook_config = {'server': SERVER, 'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -171,10 +189,13 @@ def test_ping_monitor_config_api_key_no_zabbix_data_exit_early(): ) -def test_ping_monitor_config_itemid_no_auth_data_exit_early(): +def test_ping_monitor_config_itemid_no_auth_data_bails(): # This test should exit early since there is no authentication provided # and Zabbix requires authentication to use it's API hook_config = {'server': SERVER, 'itemid': ITEMID} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -188,10 +209,13 @@ def test_ping_monitor_config_itemid_no_auth_data_exit_early(): ) -def test_ping_monitor_config_host_and_key_no_auth_data_exit_early(): +def test_ping_monitor_config_host_and_key_no_auth_data_bails(): # This test should exit early since there is no authentication provided # and Zabbix requires authentication to use it's API hook_config = {'server': SERVER, 'host': HOST, 'key': KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -209,6 +233,9 @@ def test_ping_monitor_config_host_and_key_with_api_key_auth_data_successful(): # This test should simulate a successful POST to a Zabbix server. This test uses API_KEY # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'host': HOST, 'key': KEY, 'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{SERVER}', headers=AUTH_HEADERS_API_KEY, @@ -226,8 +253,11 @@ def test_ping_monitor_config_host_and_key_with_api_key_auth_data_successful(): ) -def test_ping_monitor_config_host_and_missing_key_exits_early(): +def test_ping_monitor_config_host_and_missing_key_bails(): hook_config = {'server': SERVER, 'host': HOST, 'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -241,8 +271,11 @@ def test_ping_monitor_config_host_and_missing_key_exits_early(): ) -def test_ping_monitor_config_key_and_missing_host_exits_early(): +def test_ping_monitor_config_key_and_missing_host_bails(): hook_config = {'server': SERVER, 'key': KEY, 'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -267,6 +300,9 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_succe 'password': PASSWORD, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) auth_response = flexmock(ok=True) auth_response.should_receive('json').and_return( {'jsonrpc': '2.0', 'result': '3fe6ed01a69ebd79907a120bcd04e494', 'id': 1} @@ -296,7 +332,7 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_succe ) -def test_ping_monitor_config_host_and_key_with_username_password_auth_data_and_auth_post_error_exits_early(): +def test_ping_monitor_config_host_and_key_with_username_password_auth_data_and_auth_post_error_bails(): hook_config = { 'server': SERVER, 'host': HOST, @@ -305,6 +341,9 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_and_a 'password': PASSWORD, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) auth_response = flexmock(ok=False) auth_response.should_receive('json').and_return( {'jsonrpc': '2.0', 'result': '3fe6ed01a69ebd79907a120bcd04e494', 'id': 1} @@ -335,7 +374,7 @@ def test_ping_monitor_config_host_and_key_with_username_password_auth_data_and_a ) -def test_ping_monitor_config_host_and_key_with_username_and_missing_password_exits_early(): +def test_ping_monitor_config_host_and_key_with_username_and_missing_password_bails(): hook_config = { 'server': SERVER, 'host': HOST, @@ -343,6 +382,9 @@ def test_ping_monitor_config_host_and_key_with_username_and_missing_password_exi 'username': USERNAME, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -356,7 +398,7 @@ def test_ping_monitor_config_host_and_key_with_username_and_missing_password_exi ) -def test_ping_monitor_config_host_and_key_with_passing_and_missing_username_exits_early(): +def test_ping_monitor_config_host_and_key_with_password_and_missing_username_bails(): hook_config = { 'server': SERVER, 'host': HOST, @@ -364,6 +406,9 @@ def test_ping_monitor_config_host_and_key_with_passing_and_missing_username_exit 'password': PASSWORD, } + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.logger).should_receive('warning').once() flexmock(module.requests).should_receive('post').never() @@ -381,6 +426,9 @@ def test_ping_monitor_config_itemid_with_api_key_auth_data_successful(): # This test should simulate a successful POST to a Zabbix server. This test uses API_KEY # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'itemid': ITEMID, 'api_key': API_KEY} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) flexmock(module.requests).should_receive('post').with_args( f'{SERVER}', headers=AUTH_HEADERS_API_KEY, @@ -403,6 +451,9 @@ def test_ping_monitor_config_itemid_with_username_password_auth_data_successful( # to authenticate and HOST/KEY to know which item to populate in Zabbix. hook_config = {'server': SERVER, 'itemid': ITEMID, 'username': USERNAME, 'password': PASSWORD} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) auth_response = flexmock(ok=True) auth_response.should_receive('json').and_return( {'jsonrpc': '2.0', 'result': '3fe6ed01a69ebd79907a120bcd04e494', 'id': 1} @@ -432,9 +483,12 @@ def test_ping_monitor_config_itemid_with_username_password_auth_data_successful( ) -def test_ping_monitor_config_itemid_with_username_password_auth_data_and_push_post_error_exits_early(): +def test_ping_monitor_config_itemid_with_username_password_auth_data_and_push_post_error_bails(): hook_config = {'server': SERVER, 'itemid': ITEMID, 'username': USERNAME, 'password': PASSWORD} + flexmock(module.borgmatic.hooks.credential.tag).should_receive( + 'resolve_credential' + ).replace_with(lambda value: value) auth_response = flexmock(ok=True) auth_response.should_receive('json').and_return( {'jsonrpc': '2.0', 'result': '3fe6ed01a69ebd79907a120bcd04e494', 'id': 1}