From 11253d2b1d020ecda159197eea6546e63e6fbc2b Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Tue, 30 Dec 2025 23:19:10 -0800 Subject: [PATCH] Get existing test passing. --- tests/integration/test_execute.py | 12 ++++-- tests/unit/borg/test_info.py | 6 +++ tests/unit/borg/test_repo_delete.py | 12 ++++-- tests/unit/test_execute.py | 54 ++++++++++++------------- tests/unit/test_logger.py | 61 +++++++++++++++++++++++++++-- 5 files changed, 108 insertions(+), 37 deletions(-) diff --git a/tests/integration/test_execute.py b/tests/integration/test_execute.py index f7ef2e61..279aac80 100644 --- a/tests/integration/test_execute.py +++ b/tests/integration/test_execute.py @@ -15,7 +15,9 @@ def test_log_outputs_logs_each_line_separately(): levelname='INFO', getMessage=lambda: 'hi', ) - flexmock(module).should_receive('line_to_log_record').with_args('hi', logging.INFO).and_return(hi_record) + flexmock(module).should_receive('line_to_log_record').with_args('hi', logging.INFO).and_return( + hi_record + ) flexmock(module.logger).should_receive('handle').with_args(hi_record).once() there_record = flexmock( msg='there', @@ -23,7 +25,9 @@ def test_log_outputs_logs_each_line_separately(): levelname='INFO', getMessage=lambda: 'there', ) - flexmock(module).should_receive('line_to_log_record').with_args('there', logging.INFO).and_return(there_record) + flexmock(module).should_receive('line_to_log_record').with_args( + 'there', logging.INFO + ).and_return(there_record) flexmock(module.logger).should_receive('handle').with_args(there_record).once() flexmock(module).should_receive('interpret_exit_code').and_return(module.Exit_status.SUCCESS) @@ -56,7 +60,9 @@ def test_log_outputs_skips_logs_for_process_with_none_stdout(): levelname='INFO', getMessage=lambda: 'there', ) - flexmock(module).should_receive('line_to_log_record').with_args('there', logging.INFO).and_return(there_record) + flexmock(module).should_receive('line_to_log_record').with_args( + 'there', logging.INFO + ).and_return(there_record) flexmock(module.logger).should_receive('handle').with_args(there_record).once() flexmock(module).should_receive('interpret_exit_code').and_return(module.Exit_status.SUCCESS) diff --git a/tests/unit/borg/test_info.py b/tests/unit/borg/test_info.py index f1088a84..af31e4f0 100644 --- a/tests/unit/borg/test_info.py +++ b/tests/unit/borg/test_info.py @@ -566,6 +566,8 @@ def test_make_info_command_with_date_based_matching_passes_through_to_command(): def test_display_archives_info_calls_two_commands(): + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_info_command') flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -583,6 +585,8 @@ def test_display_archives_info_calls_two_commands(): def test_display_archives_info_with_json_calls_json_command_only(): + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_info_command') flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None) @@ -604,6 +608,8 @@ def test_display_archives_info_with_json_calls_json_command_only(): def test_display_archives_info_calls_borg_with_working_directory(): + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER flexmock(module).should_receive('make_info_command') flexmock(module.environment).should_receive('make_environment') flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return( diff --git a/tests/unit/borg/test_repo_delete.py b/tests/unit/borg/test_repo_delete.py index a4934431..727d97f7 100644 --- a/tests/unit/borg/test_repo_delete.py +++ b/tests/unit/borg/test_repo_delete.py @@ -301,7 +301,8 @@ def test_make_repo_delete_command_includes_force_twice(): def test_delete_repository_with_defaults_does_not_capture_output(): - module.borgmatic.logger.add_custom_log_levels() + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -330,7 +331,8 @@ def test_delete_repository_with_defaults_does_not_capture_output(): def test_delete_repository_with_force_captures_output(): - module.borgmatic.logger.add_custom_log_levels() + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -359,7 +361,8 @@ def test_delete_repository_with_force_captures_output(): def test_delete_repository_with_cache_only_captures_output(): - module.borgmatic.logger.add_custom_log_levels() + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( @@ -388,7 +391,8 @@ def test_delete_repository_with_cache_only_captures_output(): def test_delete_repository_calls_borg_with_working_directory(): - module.borgmatic.logger.add_custom_log_levels() + flexmock(module.borgmatic.logger).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.borgmatic.logger.ANSWER command = flexmock() flexmock(module).should_receive('make_repo_delete_command').and_return(command) flexmock(module.borgmatic.borg.environment).should_receive('make_environment').and_return( diff --git a/tests/unit/test_execute.py b/tests/unit/test_execute.py index c17eea0a..1acc798f 100644 --- a/tests/unit/test_execute.py +++ b/tests/unit/test_execute.py @@ -68,63 +68,63 @@ def test_command_for_process_passes_through_string_command(): assert module.command_for_process(process) == 'foo bar baz' -def test_output_buffer_for_process_returns_stderr_when_stdout_excluded(): +def test_output_buffers_for_process_returns_stdout_and_stderr_by_default(): stdout = flexmock() stderr = flexmock() process = flexmock(stdout=stdout, stderr=stderr) - assert module.output_buffer_for_process(process, exclude_stdouts=[flexmock(), stdout]) == stderr - - -def test_output_buffer_for_process_returns_stdout_when_not_excluded(): - stdout = flexmock() - process = flexmock(stdout=stdout) - - assert ( - module.output_buffer_for_process(process, exclude_stdouts=[flexmock(), flexmock()]) - == stdout + assert module.output_buffers_for_process(process, exclude_stdouts=[flexmock(), flexmock()]) == ( + stdout, + stderr, ) -def test_log_line_under_max_line_count_appends(): - last_lines = ['last'] - flexmock(module.logger).should_receive('log').once() +def test_output_buffers_for_process_returns_stderr_only_when_stdout_excluded(): + stdout = flexmock() + stderr = flexmock() + process = flexmock(stdout=stdout, stderr=stderr) - module.log_line( + assert module.output_buffers_for_process(process, exclude_stdouts=[flexmock(), stdout]) == ( + stderr, + ) + + +def test_handle_log_record_under_max_line_count_appends(): + last_lines = ['last'] + flexmock(module.logger).should_receive('handle').once() + + module.handle_log_record( + flexmock(levelno=module.logging.INFO, getMessage=lambda: 'line'), last_lines, captured_output=flexmock(), - line='line', - default_log_level=flexmock(), ) assert last_lines == ['last', 'line'] -def test_log_line_over_max_line_count_trims_and_appends(): +def test_handle_log_record_over_max_line_count_trims_and_appends(): original_last_lines = [str(number) for number in range(module.ERROR_OUTPUT_MAX_LINE_COUNT)] last_lines = list(original_last_lines) - flexmock(module.logger).should_receive('log').once() + flexmock(module.logger).should_receive('handle').once() - module.log_line( + module.handle_log_record( + flexmock(levelno=module.logging.INFO, getMessage=lambda: 'line'), last_lines, captured_output=flexmock(), - line='line', - default_log_level=flexmock(), ) assert last_lines == [*original_last_lines[1:], 'line'] -def test_log_line_with_output_log_level_none_appends_captured_output(): +def test_handle_log_record_with_output_log_level_none_appends_captured_output(): last_lines = ['last'] captured_output = ['captured'] - flexmock(module.logger).should_receive('log').never() + flexmock(module.logger).should_receive('handle').never() - module.log_line( + module.handle_log_record( + flexmock(levelno=None, getMessage=lambda: 'line'), last_lines, captured_output=captured_output, - line='line', - default_log_level=None, ) assert captured_output == ['captured', 'line'] diff --git a/tests/unit/test_logger.py b/tests/unit/test_logger.py index 6b092e9d..c30d5ca6 100644 --- a/tests/unit/test_logger.py +++ b/tests/unit/test_logger.py @@ -447,6 +447,7 @@ def test_flush_delayed_logging_flushes_delayed_logging_handler(): def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.ANSWER + flexmock(module.logging).DISABLED = module.DISABLED fake_formatter = flexmock() flexmock(module).should_receive('Console_color_formatter').and_return(fake_formatter) multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO) @@ -458,8 +459,15 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux( level=logging.DEBUG, handlers=list, ) + flexmock(module.os.path).should_receive('exists').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(True) - syslog_handler = logging.handlers.SysLogHandler() + syslog_handler = flexmock( + level=module.logging.DEBUG, + setLevel=lambda log_level: None, + setFormatter=lambda formatter: None, + ) flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( address='/dev/log', ).and_return(syslog_handler).once() @@ -470,6 +478,7 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_linux( def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.ANSWER + flexmock(module.logging).DISABLED = module.DISABLED fake_formatter = flexmock() flexmock(module).should_receive('Console_color_formatter').and_return(fake_formatter) multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO) @@ -481,9 +490,16 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos( level=logging.DEBUG, handlers=list, ) + flexmock(module.os.path).should_receive('exists').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/syslog').and_return(True) - syslog_handler = logging.handlers.SysLogHandler() + syslog_handler = flexmock( + level=module.logging.DEBUG, + setLevel=lambda log_level: None, + setFormatter=lambda formatter: None, + ) flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( address='/var/run/syslog', ).and_return(syslog_handler).once() @@ -494,6 +510,7 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_macos( def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebsd(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.ANSWER + flexmock(module.logging).DISABLED = module.DISABLED fake_formatter = flexmock() flexmock(module).should_receive('Console_color_formatter').and_return(fake_formatter) multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO) @@ -505,10 +522,17 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebs level=logging.DEBUG, handlers=list, ) + flexmock(module.os.path).should_receive('exists').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/syslog').and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/var/run/log').and_return(True) - syslog_handler = logging.handlers.SysLogHandler() + syslog_handler = flexmock( + level=module.logging.DEBUG, + setLevel=lambda log_level: None, + setFormatter=lambda formatter: None, + ) flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args( address='/var/run/log', ).and_return(syslog_handler).once() @@ -516,6 +540,34 @@ def test_configure_logging_with_syslog_log_level_probes_for_log_socket_on_freebs module.configure_logging(logging.INFO, syslog_log_level=logging.DEBUG) +def test_configure_logging_with_journald_probes_for_log_socket(): + flexmock(module).should_receive('add_custom_log_levels') + flexmock(module.logging).ANSWER = module.ANSWER + flexmock(module.logging).DISABLED = module.DISABLED + fake_formatter = flexmock() + flexmock(module).should_receive('Console_color_formatter').and_return(fake_formatter) + multi_stream_handler = flexmock(setLevel=lambda level: None, level=logging.INFO) + multi_stream_handler.should_receive('setFormatter').with_args(fake_formatter).once() + flexmock(module).should_receive('Multi_stream_handler').and_return(multi_stream_handler) + flexmock(module).should_receive('interactive_console').and_return(False) + flexmock(module).should_receive('flush_delayed_logging') + flexmock(module.logging).should_receive('basicConfig').with_args( + level=logging.DEBUG, + handlers=list, + ) + flexmock(module.os.path).should_receive('exists').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(True) + journald_handler = flexmock(level=module.logging.DEBUG, setLevel=lambda log_level: None) + flexmock(module).should_receive('JournaldHandler').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(journald_handler).once() + flexmock(module.os.path).should_receive('exists').with_args('/dev/log').never() + flexmock(module.logging.handlers).should_receive('SysLogHandler').never() + + module.configure_logging(logging.INFO, syslog_log_level=logging.DEBUG) + + def test_configure_logging_without_syslog_log_level_skips_syslog(): flexmock(module).should_receive('add_custom_log_levels') flexmock(module.logging).ANSWER = module.ANSWER @@ -622,6 +674,9 @@ def test_configure_logging_to_both_log_file_and_syslog(): level=logging.DEBUG, handlers=list, ) + flexmock(module.os.path).should_receive('exists').with_args( + module.JOURNALD_SOCKET_PATH + ).and_return(False) flexmock(module.os.path).should_receive('exists').with_args('/dev/log').and_return(True) syslog_handler = logging.handlers.SysLogHandler() flexmock(module.logging.handlers).should_receive('SysLogHandler').with_args(