From e1808041d8767830facadcbe50fd479f7ac9c763 Mon Sep 17 00:00:00 2001 From: Mariano Koremblum Date: Mon, 27 Sep 2021 13:46:39 -0300 Subject: [PATCH] ITs further fixes and improvements --- ...wazuh_macos_file_status_when_no_macos.yaml | 16 +++-- .../test_macos_file_status_basic.py | 71 ++++++++++++------- .../test_macos_file_status_predicate.py | 33 +++------ .../test_macos_file_status_when_no_macos.py | 65 ++++++++++++----- 4 files changed, 112 insertions(+), 73 deletions(-) diff --git a/tests/integration/test_logcollector/test_macos/data/wazuh_macos_file_status_when_no_macos.yaml b/tests/integration/test_logcollector/test_macos/data/wazuh_macos_file_status_when_no_macos.yaml index ec3fe601e4..055f732234 100644 --- a/tests/integration/test_logcollector/test_macos/data/wazuh_macos_file_status_when_no_macos.yaml +++ b/tests/integration/test_logcollector/test_macos/data/wazuh_macos_file_status_when_no_macos.yaml @@ -3,11 +3,13 @@ apply_to_modules: - test_macos_file_status_when_no_macos sections: - - section: client + - section: localfile + attributes: + - name: 'localfile_dummy_block' elements: - - server: - elements: - - address: - value: '127.0.0.1' - - protocol: - value: 'tcp' + - location: + value: FILE_TO_MONITOR + - log_format: + value: 'syslog' + - only-future-events: + value: 'yes' diff --git a/tests/integration/test_logcollector/test_macos/test_macos_file_status_basic.py b/tests/integration/test_logcollector/test_macos/test_macos_file_status_basic.py index 0e1ab92706..0c4ba26af9 100644 --- a/tests/integration/test_logcollector/test_macos/test_macos_file_status_basic.py +++ b/tests/integration/test_logcollector/test_macos/test_macos_file_status_basic.py @@ -7,10 +7,12 @@ import pytest import wazuh_testing.logcollector as logcollector -from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH +from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH, WAZUH_LOCAL_INTERNAL_OPTIONS +from wazuh_testing.tools.monitoring import FileMonitor, wait_file, make_callback from wazuh_testing.tools.configuration import load_wazuh_configurations -from wazuh_testing.tools.monitoring import FileMonitor, wait_file +from wazuh_testing.logcollector import prefix as logcollector_prefix from wazuh_testing.tools.file import read_json, truncate_file +from wazuh_testing.tools.services import control_service # Marks pytestmark = [pytest.mark.darwin, pytest.mark.tier(level=0)] @@ -33,7 +35,8 @@ # Time in seconds to update the file_status.json file_status_update_time = 4 -local_internal_options = { 'logcollector.vcheck_files': file_status_update_time, +local_internal_options = { 'logcollector.debug': 2, + 'logcollector.vcheck_files': file_status_update_time, 'logcollector.sample_log_length': sample_log_length } macos_message = { 'command': 'logger', @@ -42,17 +45,18 @@ # Maximum waiting time in seconds to find the logs on ossec.log file_monitor_timeout = 30 -wazuh_log_monitor = None - +# Expected message to be used on the "callback_macos_uls_log" callback expected_message = logcollector.format_macos_message_pattern(macos_message['command'], macos_message['message']) +wazuh_log_monitor = None + # Fixtures @pytest.fixture(scope='module') def startup_cleanup(): """Truncate ossec.log and remove logcollector's file_status.json file.""" - truncate_file(LOG_FILE_PATH) - os.remove(LOGCOLLECTOR_FILE_STATUS_PATH) if os.path.exists(LOGCOLLECTOR_FILE_STATUS_PATH) else None + truncate_file(WAZUH_LOCAL_INTERNAL_OPTIONS) + @pytest.fixture(scope='module') def get_local_internal_options(): @@ -66,34 +70,47 @@ def get_configuration(request): return request.param -def wait_macos_uls_log(line): - """Callback function to wait for the macOS' ULS log collected by logcollector.""" - if re.search(expected_message, line): - return True +@pytest.fixture(scope='module') +def restart_required_logcollector_daemons(): + """Wazuh logcollector daemons handler.""" - return None + required_logcollector_daemons = ['wazuh-logcollector'] + for daemon in required_logcollector_daemons: + control_service('stop', daemon=daemon) + + truncate_file(LOG_FILE_PATH) + os.remove(LOGCOLLECTOR_FILE_STATUS_PATH) if os.path.exists(LOGCOLLECTOR_FILE_STATUS_PATH) else None + + for daemon in required_logcollector_daemons: + control_service('start', daemon=daemon) + + yield + + for daemon in required_logcollector_daemons: + control_service('stop', daemon=daemon) + + +def callback_macos_uls_log(): + """Callback function to wait for the macOS' ULS log collected by logcollector.""" + return make_callback(pattern=expected_message, prefix=logcollector_prefix, escape=False) -def wait_logcollector_log_stream(line): - """Check if 'line' has the logcollector's macOS ULS module start message.""" - if re.search(r'Monitoring macOS logs with: (.+?)log stream', line): - return True - return None +def callback_logcollector_log_stream_log(): + """Check for logcollector's macOS ULS module start message.""" + return make_callback(pattern='Monitoring macOS logs with:(.+?)log stream', prefix=logcollector_prefix, escape=False) -def wait_macos_key_file_status(line): - """Check if 'line' has the 'macos' key on it.""" - if re.search(r'macos', line): - return True - return None +def callback_file_status_macos_key(line): + """Check for 'macos' key.""" + return make_callback(pattern='"macos"', prefix='') def test_macos_file_status_basic(startup_cleanup, - configure_local_internal_options, + configure_local_internal_options_module, get_configuration, configure_environment, - daemons_handler): + restart_required_logcollector_daemons): """Checks if logcollector stores correctly "macos"-formatted localfile data. This test uses logger tool and a custom log to generate an ULS event. The agent is connected to the authd simulator @@ -112,13 +129,13 @@ def test_macos_file_status_basic(startup_cleanup, # Watches the ossec.log to check when logcollector starts the macOS ULS module wazuh_log_monitor.start(timeout=file_monitor_timeout, - callback=wait_logcollector_log_stream, + callback=callback_logcollector_log_stream_log(), error_message='Logcollector did not start') logcollector.generate_macos_logger_log(macos_message['message']) wazuh_log_monitor.start(timeout=file_monitor_timeout, - callback=wait_macos_uls_log, + callback=callback_macos_uls_log(), error_message='MacOS ULS log was not found') # Waits for file_status.json to be created, with a timeout about the time needed to update the file @@ -127,7 +144,7 @@ def test_macos_file_status_basic(startup_cleanup, # Watches the file_status.json file for the "macos" key file_status_monitor = FileMonitor(LOGCOLLECTOR_FILE_STATUS_PATH) file_status_monitor.start(timeout=file_monitor_timeout, - callback=wait_macos_key_file_status, + callback=callback_file_status_macos_key, error_message="The 'macos' key could not be found on the file_status.json file") file_status_json = read_json(LOGCOLLECTOR_FILE_STATUS_PATH) diff --git a/tests/integration/test_logcollector/test_macos/test_macos_file_status_predicate.py b/tests/integration/test_logcollector/test_macos/test_macos_file_status_predicate.py index b222c4523a..82b1ffbda3 100644 --- a/tests/integration/test_logcollector/test_macos/test_macos_file_status_predicate.py +++ b/tests/integration/test_logcollector/test_macos/test_macos_file_status_predicate.py @@ -7,9 +7,10 @@ import re # from wazuh_testing.logcollector import DEFAULT_AUTHD_REMOTED_SIMULATOR_CONFIGURATION -from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH +from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH, WAZUH_LOCAL_INTERNAL_OPTIONS +from wazuh_testing.tools.monitoring import FileMonitor, wait_file, make_callback from wazuh_testing.tools.configuration import load_wazuh_configurations -from wazuh_testing.tools.monitoring import FileMonitor, wait_file +from wazuh_testing.logcollector import prefix as logcollector_prefix from wazuh_testing.tools.file import read_json, truncate_file # Marks @@ -46,44 +47,32 @@ @pytest.fixture(scope='module') def startup_cleanup(): """Truncate ossec.log and remove logcollector's file_status.json file.""" + truncate_file(WAZUH_LOCAL_INTERNAL_OPTIONS) truncate_file(LOG_FILE_PATH) os.remove(LOGCOLLECTOR_FILE_STATUS_PATH) if os.path.exists(LOGCOLLECTOR_FILE_STATUS_PATH) else None -@pytest.fixture(scope='module') -def get_local_internal_options(): - """Get configurations from the module.""" - return local_internal_options - - @pytest.fixture(scope='module', params=configurations, ids=configuration_ids) def get_configuration(request): """Get configurations from the module.""" return request.param -def callback_log_bad_predicate(line): +def callback_log_bad_predicate(): """Check if 'line' has the macOS ULS bad predicate message on it.""" - match = re.match(r'.*Execution error \'log:', line) - if match: - return True - return None + return make_callback(pattern="Execution error 'log:", prefix=logcollector_prefix) -def callback_log_exit_log(line): +def callback_log_exit_log(): """Check if 'line' has the macOS ULS log stream exited message on it.""" - match = re.match(r'.*macOS \'log stream\' process exited, pid:', line) - if match: - return True - return None + return make_callback(pattern="macOS 'log stream' process exited, pid:", prefix=logcollector_prefix) def test_macos_file_status_predicate(startup_cleanup, - configure_local_internal_options, + configure_local_internal_options_module, get_configuration, configure_environment, daemons_handler): - """Checks that logcollector does not store 'macos'-formatted localfile data since its predicate is erroneous. The agent is connected to the authd simulator and uses a dummy localfile (/Library/Ossec/logs/active-responses.log) @@ -96,12 +85,12 @@ def test_macos_file_status_predicate(startup_cleanup, wazuh_log_monitor = FileMonitor(LOG_FILE_PATH) wazuh_log_monitor.start(timeout=file_monitor_timeout, - callback=callback_log_bad_predicate, + callback=callback_log_bad_predicate(), error_message='Expected log that matches the regex ' '".*Execution error \'log:" could not be found') wazuh_log_monitor.start(timeout=file_monitor_timeout, - callback=callback_log_exit_log, + callback=callback_log_exit_log(), error_message='Expected log that matches the regex ' '".*macOS \'log stream\' process exited, pid:" could not be found') diff --git a/tests/integration/test_logcollector/test_macos/test_macos_file_status_when_no_macos.py b/tests/integration/test_logcollector/test_macos/test_macos_file_status_when_no_macos.py index ca58841e28..77a9ed860f 100644 --- a/tests/integration/test_logcollector/test_macos/test_macos_file_status_when_no_macos.py +++ b/tests/integration/test_logcollector/test_macos/test_macos_file_status_when_no_macos.py @@ -6,10 +6,13 @@ import pytest import wazuh_testing.logcollector as logcollector +from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH, WAZUH_LOCAL_INTERNAL_OPTIONS +from wazuh_testing.tools.monitoring import FileMonitor, wait_file, make_callback from wazuh_testing.tools.file import read_json, write_json_file, truncate_file -from wazuh_testing.tools import LOGCOLLECTOR_FILE_STATUS_PATH, LOG_FILE_PATH from wazuh_testing.tools.configuration import load_wazuh_configurations -from wazuh_testing.tools.monitoring import FileMonitor, wait_file +from wazuh_testing.logcollector import prefix as logcollector_prefix +from wazuh_testing.tools.services import control_service +from tempfile import gettempdir from time import sleep # Marks @@ -19,10 +22,12 @@ test_data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') configurations_path = os.path.join(test_data_path, 'wazuh_macos_file_status_when_no_macos.yaml') -daemons_handler_configuration = {'daemons': ['wazuh-logcollector'], 'ignore_errors': False} +dummy_file = os.path.join(gettempdir(), 'dummy_file.log') +parameters = [{'FILE_TO_MONITOR': dummy_file}] # Configuration data -configurations = load_wazuh_configurations(configurations_path, __name__) +configurations = load_wazuh_configurations(configurations_path, __name__, params=parameters) +configuration_ids = [f"{x['FILE_TO_MONITOR']}" for x in parameters] # Max number of characters to be displayed in the log's debug message sample_log_length = 100 @@ -35,37 +40,59 @@ # Maximum waiting time in seconds to find the logs on ossec.log file_monitor_timeout = 30 +# Time to wait for file_status.json to be updated wait_file_status_update_time = file_status_update_time + 2 wazuh_log_monitor = None # Fixtures +@pytest.fixture(scope='module', params=configurations, ids=configuration_ids) +def get_configuration(request): + """Get configurations from the module.""" + return request.param + + @pytest.fixture(scope='module') -def startup_cleanup(): - """Truncate ossec.log and remove logcollector's file_status.json file.""" +def restart_required_logcollector_daemons(): + """Wazuh logcollector daemons handler.""" + + required_logcollector_daemons = ['wazuh-logcollector'] + + for daemon in required_logcollector_daemons: + control_service('stop', daemon=daemon) + truncate_file(LOG_FILE_PATH) os.remove(LOGCOLLECTOR_FILE_STATUS_PATH) if os.path.exists(LOGCOLLECTOR_FILE_STATUS_PATH) else None + for daemon in required_logcollector_daemons: + control_service('start', daemon=daemon) + + yield + + for daemon in required_logcollector_daemons: + control_service('stop', daemon=daemon) + @pytest.fixture(scope='module') -def get_local_internal_options(): - """Get configurations from the module.""" - return local_internal_options +def startup_cleanup(): + """Truncate local_internals file and create dummy file to be monitored by logcollector.""" + truncate_file(WAZUH_LOCAL_INTERNAL_OPTIONS) + with open(dummy_file, 'w') as f: + pass -@pytest.fixture(scope='module', params=configurations) -def get_configuration(request): - """Get configurations from the module.""" - return request.param + +def callback_logcollector_started(): + """Check for 'macos' key.""" + return make_callback(pattern='Started', prefix=logcollector_prefix) def test_macos_file_status_when_no_macos(startup_cleanup, - configure_local_internal_options, + configure_local_internal_options_module, get_configuration, configure_environment, - daemons_handler): - + restart_required_logcollector_daemons): """Checks that logcollector does not store and removes, if exists, previous "macos"-formatted localfile data in the file_status.json @@ -77,10 +104,14 @@ def test_macos_file_status_when_no_macos(startup_cleanup, TimeoutError: If the callbacks, that checks the expected logs, are not satisfied in the expected time. """ - file_status_json = '' + file_status_json = {} wazuh_log_monitor = FileMonitor(LOG_FILE_PATH) + wazuh_log_monitor.start(timeout=file_monitor_timeout, + callback=callback_logcollector_started(), + error_message="Logcollector did not start") + # Check if json_status contains 'macos' data and if not insert it if os.path.exists(LOGCOLLECTOR_FILE_STATUS_PATH): file_status_json = read_json(LOGCOLLECTOR_FILE_STATUS_PATH)