From 2cf4762928d64e87f6eb9ec53fe07b0e094c43d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Thu, 6 May 2021 18:47:11 +0200 Subject: [PATCH 1/9] Create logcollector reconnect_time test --- .../wazuh_testing/tools/services.py | 29 ++++- .../data/wazuh_reconnect_time.yaml | 13 ++ .../test_reconnect_time.py | 117 ++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/integration/test_logcollector/test_reconnect_time/data/wazuh_reconnect_time.yaml create mode 100644 tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py diff --git a/deps/wazuh_testing/wazuh_testing/tools/services.py b/deps/wazuh_testing/wazuh_testing/tools/services.py index c32a905277..659bdaf533 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/services.py +++ b/deps/wazuh_testing/wazuh_testing/tools/services.py @@ -204,7 +204,7 @@ def check_daemon_status(daemon=None, running=True, timeout=10, extra_sockets=Non # Finish main for loop if both daemon and socket checks are ok break - time.sleep(timeout/3) + time.sleep(timeout / 3) else: raise TimeoutError(f"{'wazuh-service' if daemon is None else daemon} " f"{'is not' if running else 'is'} running") @@ -234,3 +234,30 @@ def check_if_process_is_running(process_name): pass return is_running + + +def control_event_log_service(control): + """Control Windows event log service + + Args: + control (str): Start or Stop + """ + for _ in range(10): + control_sc = 'disabled' if control == 'stop' else 'auto' + + command = subprocess.run(f'sc config eventlog start= {control_sc}', stderr=subprocess.PIPE) + result = command.returncode + if result != 0: + raise ValueError(f'Event log service did not stop correctly') + + command = subprocess.run(f"net {control} eventlog /y", stderr=subprocess.PIPE) + result = command.returncode + if result == 0: + break + else: + time.sleep(1) + else: + raise ValueError(f"Event log service did not stop correctly") + + time.sleep(1) + diff --git a/tests/integration/test_logcollector/test_reconnect_time/data/wazuh_reconnect_time.yaml b/tests/integration/test_logcollector/test_reconnect_time/data/wazuh_reconnect_time.yaml new file mode 100644 index 0000000000..79d138b11a --- /dev/null +++ b/tests/integration/test_logcollector/test_reconnect_time/data/wazuh_reconnect_time.yaml @@ -0,0 +1,13 @@ +- tags: + - test_reconnect_time + apply_to_modules: + - test_reconnect_time + sections: + - section: localfile + elements: + - location: + value: LOCATION + - log_format: + value: LOG_FORMAT + - reconnect_time: + value: RECONNECT_TIME \ No newline at end of file diff --git a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py new file mode 100644 index 0000000000..8b7a8ef97c --- /dev/null +++ b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py @@ -0,0 +1,117 @@ +# Copyright (C) 2015-2021, Wazuh Inc. +# Created by Wazuh, Inc. . +# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2 +import os +import pytest +from datetime import timedelta, datetime +import time +import sys +from wazuh_testing.tools.configuration import load_wazuh_configurations +from wazuh_testing import global_parameters, logger +from wazuh_testing.tools.time import TimeMachine +import wazuh_testing.logcollector as logcollector +from wazuh_testing.tools.time import time_to_seconds +import wazuh_testing.tools.services as services + +if sys.platform != 'win32': + pytestmark = [pytest.mark.skip, pytest.mark.tier(level=0)] +else: + pytestmark = pytest.mark.tier(level=0) + +local_internal_options = { + 'logcollector.remote_commands': 1, + 'logcollector.debug': 2, + 'monitord.rotate_log': 0 +} + +# Configuration +test_data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') +configurations_path = os.path.join(test_data_path, 'wazuh_reconnect_time.yaml') + +default_value = '5s' +parameters = [ + {'LOCATION': 'Application', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '5s'}, + {'LOCATION': 'Security', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '5s'}, + {'LOCATION': 'System', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '5s'}, + {'LOCATION': 'Application', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '40m'}, + {'LOCATION': 'Security', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '40m'}, + {'LOCATION': 'System', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '40m'}, + {'LOCATION': 'Application', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '20h'}, + {'LOCATION': 'Security', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '20h'}, + {'LOCATION': 'System', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '20h'}, + +] +metadata = [ + {'location': 'Application', 'log_format': 'eventchannel', 'reconnect_time': '5s'}, + {'location': 'Security', 'log_format': 'eventchannel', 'reconnect_time': '5s'}, + {'location': 'System', 'log_format': 'eventchannel', 'reconnect_time': '5s'}, + {'location': 'Application', 'log_format': 'eventchannel', 'reconnect_time': '40m'}, + {'location': 'Security', 'log_format': 'eventchannel', 'reconnect_time': '40m'}, + {'location': 'System', 'log_format': 'eventchannel', 'reconnect_time': '40m'}, + {'location': 'Application', 'log_format': 'eventchannel', 'reconnect_time': '20h'}, + {'location': 'Security', 'log_format': 'eventchannel', 'reconnect_time': '20h'}, + {'location': 'System', 'log_format': 'eventchannel', 'reconnect_time': '20h'}, +] +configurations = load_wazuh_configurations(configurations_path, __name__, + params=parameters, + metadata=metadata) +configuration_ids = [f"{x['LOCATION'], x['LOG_FORMAT'], x['RECONNECT_TIME']}" for x in parameters] + + +@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 get_local_internal_options(): + """Get configurations from the module.""" + return local_internal_options + + +def test_reconnect_time(get_local_internal_options, configure_local_internal_options, get_configuration, + configure_environment, restart_logcollector): + """Check if reconnect_time value works properly + + Ensure correspond debug logs are generated when Windows event log service stop. Also, when event log service is + restarted, `wazuh-agent` should reconnect to it using reconnect_time value. + """ + + config = get_configuration['metadata'] + + if config['reconnect_time'] != default_value: + pytest.xfail("Expected fail: ") + + log_callback = logcollector.callback_eventchannel_analyzing(config['location']) + wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=log_callback, + error_message=logcollector.GENERIC_CALLBACK_ERROR_ANALYZING_EVENTCHANNEL) + + services.control_event_log_service('stop') + + log_callback = logcollector.callback_event_log_service_down(config['location']) + wazuh_log_monitor.start(timeout=30, callback=log_callback, + error_message=logcollector.GENERIC_CALLBACK_ERROR_ANALYZING_EVENTCHANNEL) + + log_callback = logcollector.callback_trying_to_reconnect(config['location'], + time_to_seconds(config['reconnect_time'])) + wazuh_log_monitor.start(timeout=30, callback=log_callback, + error_message=logcollector.GENERIC_CALLBACK_ERROR_ANALYZING_EVENTCHANNEL) + + services.control_event_log_service('start') + + before = str(datetime.now()) + seconds_to_travel = time_to_seconds(config['reconnect_time']) / 2 + TimeMachine.travel_to_future(timedelta(seconds=seconds_to_travel)) + logger.debug(f"Changing the system clock from {before} to {datetime.now()}") + + log_callback = logcollector.callback_reconnect_eventchannel(config['location']) + + before = str(datetime.now()) + TimeMachine.travel_to_future(timedelta(seconds=(seconds_to_travel))) + logger.debug(f"Changing the system clock from {before} to {datetime.now()}") + + wazuh_log_monitor.start(timeout=30, callback=log_callback, + error_message=logcollector.GENERIC_CALLBACK_ERROR_COMMAND_MONITORING) + + TimeMachine.time_rollback() From f853f160bd4ac401112eca31683760ebaecf01f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Thu, 6 May 2021 19:34:59 +0200 Subject: [PATCH 2/9] Add logcollector event channel reconnect callback --- .../wazuh_testing/logcollector.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/deps/wazuh_testing/wazuh_testing/logcollector.py b/deps/wazuh_testing/wazuh_testing/logcollector.py index 60556229a9..283e866b1a 100644 --- a/deps/wazuh_testing/wazuh_testing/logcollector.py +++ b/deps/wazuh_testing/wazuh_testing/logcollector.py @@ -199,3 +199,62 @@ def callback_running_command(log_format, command, prefix=monitoring.LOG_COLLECTO log_format_message = 'full command' if log_format == 'full_command' else 'command' msg = fr"DEBUG: Running {log_format_message} '{command}'" return monitoring.make_callback(pattern=msg, prefix=prefix, escape=escape) + + + +def callback_running_command(log_format, command, prefix=monitoring.LOG_COLLECTOR_DETECTOR_PREFIX, escape=False): + """Create a callback to detect "DEBUG: Running ''" debug line. + + Args: + log_format (str): Log format of the command monitoring (full_command or command). + command (str): Command to be monitored. + prefix (str): Daemon that generates the log. + escape (bool): Flag to escape special characters in the pattern. + + Returns: + callable: callback to detect this event. + """ + log_format_message = 'full command' if log_format == 'full_command' else 'command' + msg = fr"DEBUG: Running {log_format_message} '{command}'" + return monitoring.make_callback(pattern=msg, prefix=prefix, escape=escape) + + + +def callback_event_log_service_down(location, severity='WARNING'): + """Create a callback to detect "DEBUG: Running ''" debug line. + + Args: + log_format (str): Log format of the command monitoring (full_command or command). + command (str): Command to be monitored. + prefix (str): Daemon that generates the log. + escape (bool): Flag to escape special characters in the pattern. + + Returns: + callable: callback to detect this event. + """ + log_format_message = f"{severity}: The eventlog service is down. Unable to collect logs from '{location}' channel." + print(f"{log_format_message}") + return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) + +def callback_trying_to_reconnect(location, reconnect_time): + """Create a callback to detect "DEBUG: Running ''" debug line. + + Args: + log_format (str): Log format of the command monitoring (full_command or command). + command (str): Command to be monitored. + prefix (str): Daemon that generates the log. + escape (bool): Flag to escape special characters in the pattern. + + Returns: + callable: callback to detect this event. + """ + log_format_message = f"DEBUG: Trying to reconnect {location} channel in {reconnect_time} seconds." + print(f"{log_format_message}") + return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) + +def callback_reconnect_eventchannel(location): + """ + + """ + log_format_message = f"INFO: '{location}' channel has been reconnected succesfully." + return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) From a507aee461bc70f26daf9f5f18f02877e70a78a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Fri, 7 May 2021 14:50:45 +0200 Subject: [PATCH 3/9] Add issue to xfail cases for logcollector reconnect_time test --- .../test_reconnect_time/test_reconnect_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py index 8b7a8ef97c..93c36bc127 100644 --- a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py +++ b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py @@ -81,7 +81,7 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt config = get_configuration['metadata'] if config['reconnect_time'] != default_value: - pytest.xfail("Expected fail: ") + pytest.xfail("Expected fail: https://github.com/wazuh/wazuh/issues/8580 ") log_callback = logcollector.callback_eventchannel_analyzing(config['location']) wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=log_callback, From d5040c505ea4bedf178d30a0c10920ad60cc2b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Fri, 7 May 2021 15:45:08 +0200 Subject: [PATCH 4/9] Add test reconnect time documentation --- .../test_logcollector/test_reconnect_time.md | 29 +++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 30 insertions(+) create mode 100644 docs/tests/integration/test_logcollector/test_reconnect_time.md diff --git a/docs/tests/integration/test_logcollector/test_reconnect_time.md b/docs/tests/integration/test_logcollector/test_reconnect_time.md new file mode 100644 index 0000000000..e7c2ca2abe --- /dev/null +++ b/docs/tests/integration/test_logcollector/test_reconnect_time.md @@ -0,0 +1,29 @@ +# Test reconnect time + +## Overview + +Check if Wazuh Windows agent reconnect to Windows event log channels using the specified `reconnect_time` +option. These tests will disable Windows event log service and check that expected warning debugs are generated. +Then, system time is changed using `reconnect_time` value. After that, Wazuh should generate reconnect time debug log. + +## Objective + +- To confirm `reconnect_time` option works correctly. +- To confirm that Wazuh detect when Windows event log service is up. +- To confirm that Wazuh detect when Windows event log service is down. +- To confirm that Wazuh can reconnect to Windows event log service. + +## General info + +|Tier | Number of tests | Time spent | +|:--:|:--:|:--:| +| 0 | 9 | 1m4s | + +## Expected behavior + +- Fail if Wazuh agent does not reconnect to Windows event log at the time specified by `reconnect_time ` +- Fail if Wazuh agent does not generate a debug message when Windows event log is down + +## Code documentation + +::: tests.integration.test_logcollector.test_reconnect_time.test_reconnect_time \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 87726bd3c4..b4d89fa43b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -449,6 +449,7 @@ nav: - Overview: tests/integration/test_logcollector/test_command_monitoring/index.md - Test command execution: tests/integration/test_logcollector/test_command_monitoring/test_command_execution.md - Test command execution freq: tests/integration/test_logcollector/test_command_monitoring/test_command_execution_freq.md + - Test reconnect time: tests/integration/test_logcollector/test_reconnect_time.md - Logtest: - tests/integration/test_logtest/index.md - Test invalid token: tests/integration/test_logtest/test_invalid_token/test_invalid_session_token.md From 5de875d4bed390ef7709700e111682dd8ce57c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Fri, 7 May 2021 15:46:02 +0200 Subject: [PATCH 5/9] Fix logcollector reconnect_time tests for default time case --- .../test_reconnect_time.py | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py index 93c36bc127..0a4f423b15 100644 --- a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py +++ b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py @@ -28,7 +28,8 @@ test_data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') configurations_path = os.path.join(test_data_path, 'wazuh_reconnect_time.yaml') -default_value = '5s' +timeout_callback_reconnect_time = 30 + parameters = [ {'LOCATION': 'Application', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '5s'}, {'LOCATION': 'Security', 'LOG_FORMAT': 'eventchannel', 'RECONNECT_TIME': '5s'}, @@ -80,8 +81,8 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt config = get_configuration['metadata'] - if config['reconnect_time'] != default_value: - pytest.xfail("Expected fail: https://github.com/wazuh/wazuh/issues/8580 ") + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + pytest.xfail("Expected fail: ") log_callback = logcollector.callback_eventchannel_analyzing(config['location']) wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=log_callback, @@ -100,16 +101,21 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt services.control_event_log_service('start') - before = str(datetime.now()) - seconds_to_travel = time_to_seconds(config['reconnect_time']) / 2 - TimeMachine.travel_to_future(timedelta(seconds=seconds_to_travel)) - logger.debug(f"Changing the system clock from {before} to {datetime.now()}") + time.sleep(1) + + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + before = str(datetime.now()) + seconds_to_travel = time_to_seconds(config['reconnect_time']) / 2 + TimeMachine.travel_to_future(timedelta(seconds=seconds_to_travel)) + logger.debug(f"Changing the system clock from {before} to {datetime.now()}") log_callback = logcollector.callback_reconnect_eventchannel(config['location']) before = str(datetime.now()) - TimeMachine.travel_to_future(timedelta(seconds=(seconds_to_travel))) - logger.debug(f"Changing the system clock from {before} to {datetime.now()}") + + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + TimeMachine.travel_to_future(timedelta(seconds=(seconds_to_travel))) + logger.debug(f"Changing the system clock from {before} to {datetime.now()}") wazuh_log_monitor.start(timeout=30, callback=log_callback, error_message=logcollector.GENERIC_CALLBACK_ERROR_COMMAND_MONITORING) From 196a0b71da555fca3dad952f7f891cfe8fbc95f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Mon, 10 May 2021 09:31:41 +0200 Subject: [PATCH 6/9] Fix archlinux vd documentation --- ...elds_archlinux_feed.md => test_extra_tags_archlinux_feed.md} | 2 +- ...ds_archlinux_feed.md => test_missing_tags_archlinux_feed.md} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/{test_extra_fields_archlinux_feed.md => test_extra_tags_archlinux_feed.md} (68%) rename docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/{test_missing_fields_archlinux_feed.md => test_missing_tags_archlinux_feed.md} (67%) diff --git a/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_fields_archlinux_feed.md b/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_tags_archlinux_feed.md similarity index 68% rename from docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_fields_archlinux_feed.md rename to docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_tags_archlinux_feed.md index bf63a9df4c..1d82c549fd 100644 --- a/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_fields_archlinux_feed.md +++ b/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_extra_tags_archlinux_feed.md @@ -1,3 +1,3 @@ ## Code documentation -::: tests.integration.test_vulnerability_detector.test_feeds.archlinux.test_extra_fields_archlinux_feed +::: tests.integration.test_vulnerability_detector.test_feeds.archlinux.test_extra_tags_archlinux_feed diff --git a/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_fields_archlinux_feed.md b/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_tags_archlinux_feed.md similarity index 67% rename from docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_fields_archlinux_feed.md rename to docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_tags_archlinux_feed.md index b5fc4ee528..d4d318a19e 100644 --- a/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_fields_archlinux_feed.md +++ b/docs/tests/integration/test_vulnerability_detector/test_feeds/archlinux/test_missing_tags_archlinux_feed.md @@ -1,3 +1,3 @@ ## Code documentation -::: tests.integration.test_vulnerability_detector.test_feeds.archlinux.test_missing_fields_archlinux_feed \ No newline at end of file +::: tests.integration.test_vulnerability_detector.test_feeds.archlinux.test_missing_tags_archlinux_feed \ No newline at end of file From 4d788e12e477bbb1f3655163791253a96b576e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Mon, 10 May 2021 12:54:44 +0200 Subject: [PATCH 7/9] Add control_event_log_service raise documentation Add issue to xfail case description for reconnect_time logcollector test Fix minnor documentation error --- deps/wazuh_testing/wazuh_testing/logcollector.py | 8 ++++---- deps/wazuh_testing/wazuh_testing/tools/services.py | 7 +++++-- .../test_logcollector/test_reconnect_time.md | 4 ++-- .../test_reconnect_time/test_reconnect_time.py | 13 +++++-------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/logcollector.py b/deps/wazuh_testing/wazuh_testing/logcollector.py index 283e866b1a..a73bade89b 100644 --- a/deps/wazuh_testing/wazuh_testing/logcollector.py +++ b/deps/wazuh_testing/wazuh_testing/logcollector.py @@ -219,7 +219,6 @@ def callback_running_command(log_format, command, prefix=monitoring.LOG_COLLECTO return monitoring.make_callback(pattern=msg, prefix=prefix, escape=escape) - def callback_event_log_service_down(location, severity='WARNING'): """Create a callback to detect "DEBUG: Running ''" debug line. @@ -233,7 +232,6 @@ def callback_event_log_service_down(location, severity='WARNING'): callable: callback to detect this event. """ log_format_message = f"{severity}: The eventlog service is down. Unable to collect logs from '{location}' channel." - print(f"{log_format_message}") return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) def callback_trying_to_reconnect(location, reconnect_time): @@ -249,11 +247,13 @@ def callback_trying_to_reconnect(location, reconnect_time): callable: callback to detect this event. """ log_format_message = f"DEBUG: Trying to reconnect {location} channel in {reconnect_time} seconds." - print(f"{log_format_message}") return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) def callback_reconnect_eventchannel(location): - """ + """Create a callback to detect if specified channel has been reconnected successfully. + + Args: + location (str): Location channel. """ log_format_message = f"INFO: '{location}' channel has been reconnected succesfully." diff --git a/deps/wazuh_testing/wazuh_testing/tools/services.py b/deps/wazuh_testing/wazuh_testing/tools/services.py index 659bdaf533..29870e5db2 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/services.py +++ b/deps/wazuh_testing/wazuh_testing/tools/services.py @@ -237,10 +237,13 @@ def check_if_process_is_running(process_name): def control_event_log_service(control): - """Control Windows event log service + """Control Windows event log service. Args: - control (str): Start or Stop + control (str): Start or Stop. + + Raises: + ValueError: If the event log channel does not start/stop correctly. """ for _ in range(10): control_sc = 'disabled' if control == 'stop' else 'auto' diff --git a/docs/tests/integration/test_logcollector/test_reconnect_time.md b/docs/tests/integration/test_logcollector/test_reconnect_time.md index e7c2ca2abe..a458f60040 100644 --- a/docs/tests/integration/test_logcollector/test_reconnect_time.md +++ b/docs/tests/integration/test_logcollector/test_reconnect_time.md @@ -21,8 +21,8 @@ Then, system time is changed using `reconnect_time` value. After that, Wazuh sho ## Expected behavior -- Fail if Wazuh agent does not reconnect to Windows event log at the time specified by `reconnect_time ` -- Fail if Wazuh agent does not generate a debug message when Windows event log is down +- Fail if Wazuh agent does not reconnect to Windows event log at the time specified by `reconnect_time`. +- Fail if Wazuh agent does not generate a debug message when the Windows event log is down. ## Code documentation diff --git a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py index 0a4f423b15..a2a123312d 100644 --- a/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py +++ b/tests/integration/test_logcollector/test_reconnect_time/test_reconnect_time.py @@ -13,10 +13,7 @@ from wazuh_testing.tools.time import time_to_seconds import wazuh_testing.tools.services as services -if sys.platform != 'win32': - pytestmark = [pytest.mark.skip, pytest.mark.tier(level=0)] -else: - pytestmark = pytest.mark.tier(level=0) +pytestmark = [pytest.mark.win32, pytest.mark.tier(level=0)] local_internal_options = { 'logcollector.remote_commands': 1, @@ -81,8 +78,8 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt config = get_configuration['metadata'] - if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: - pytest.xfail("Expected fail: ") + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + pytest.xfail("Expected fail: https://github.com/wazuh/wazuh/issues/8580") log_callback = logcollector.callback_eventchannel_analyzing(config['location']) wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=log_callback, @@ -103,7 +100,7 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt time.sleep(1) - if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: before = str(datetime.now()) seconds_to_travel = time_to_seconds(config['reconnect_time']) / 2 TimeMachine.travel_to_future(timedelta(seconds=seconds_to_travel)) @@ -113,7 +110,7 @@ def test_reconnect_time(get_local_internal_options, configure_local_internal_opt before = str(datetime.now()) - if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: + if time_to_seconds(config['reconnect_time']) >= timeout_callback_reconnect_time: TimeMachine.travel_to_future(timedelta(seconds=(seconds_to_travel))) logger.debug(f"Changing the system clock from {before} to {datetime.now()}") From c3d207d5e8f55bdc5dadf44b9f6582f537533039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Mon, 10 May 2021 13:22:06 +0200 Subject: [PATCH 8/9] Fix logcollector callbacks documentation --- .../wazuh_testing/logcollector.py | 49 +++++-------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/deps/wazuh_testing/wazuh_testing/logcollector.py b/deps/wazuh_testing/wazuh_testing/logcollector.py index 06df5b2268..1623368068 100644 --- a/deps/wazuh_testing/wazuh_testing/logcollector.py +++ b/deps/wazuh_testing/wazuh_testing/logcollector.py @@ -15,6 +15,7 @@ else: prefix = monitoring.LOG_COLLECTOR_DETECTOR_PREFIX + def callback_analyzing_file(file): """Create a callback to detect if logcollector is monitoring a file. @@ -35,7 +36,6 @@ def callback_monitoring_command(log_format, command): Args: log_format (str): Log format of the command monitoring (full_command or command). command (str): Monitored command. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -51,7 +51,6 @@ def callback_monitoring_djb_multilog(program_name, multilog_file): Args: program_name (str): Program name of multilog file. multilog_file (str): Multilog file name. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -65,7 +64,6 @@ def callback_command_alias_output(alias): Args: alias (str): Command alias. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -79,7 +77,6 @@ def callback_eventchannel_bad_format(event_location): Args: event_location (str): Eventchannel location. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -94,7 +91,6 @@ def callback_socket_target(location, socket_name): Args: location (str): Name with the analyzed file. socket_name (str): Socket name. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -109,7 +105,6 @@ def callback_socket_not_defined(location, socket_name): Args: location (str): Name with the analyzed file. socket_name (str): Socket name. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -124,7 +119,6 @@ def callback_log_target_not_found(location, socket_name): Args: location (str): Name with the analyzed file. socket_name (str): Socket name. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -139,7 +133,6 @@ def callback_invalid_reconnection_time(severity='WARNING', default_value='5'): Args: severity (str): Severity of the error (WARNING, ERROR or CRITICAL) default_value (int): Default value used instead of specified reconnection time. - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -166,7 +159,6 @@ def callback_invalid_location_pattern(location): Args: location (str): Location pattern - prefix (str): Daemon that generates the error log. Returns: callable: callback to detect this event. @@ -180,7 +172,6 @@ def callback_read_lines(command, escape=False): Args: command (str): Command to be monitored. - prefix (str): Daemon that generates the log. escape (bool): Flag to escape special characters in the pattern. Returns: @@ -196,24 +187,6 @@ def callback_running_command(log_format, command, escape=False): Args: log_format (str): Log format of the command monitoring (full_command or command). command (str): Command to be monitored. - prefix (str): Daemon that generates the log. - escape (bool): Flag to escape special characters in the pattern. - - Returns: - callable: callback to detect this event. - """ - log_format_message = 'full command' if log_format == 'full_command' else 'command' - msg = fr"DEBUG: Running {log_format_message} '{command}'" - return monitoring.make_callback(pattern=msg, prefix=prefix, escape=escape) - - -def callback_running_command(log_format, command, prefix=monitoring.LOG_COLLECTOR_DETECTOR_PREFIX, escape=False): - """Create a callback to detect "DEBUG: Running ''" debug line. - - Args: - log_format (str): Log format of the command monitoring (full_command or command). - command (str): Command to be monitored. - prefix (str): Daemon that generates the log. escape (bool): Flag to escape special characters in the pattern. Returns: @@ -225,13 +198,11 @@ def callback_running_command(log_format, command, prefix=monitoring.LOG_COLLECTO def callback_event_log_service_down(location, severity='WARNING'): - """Create a callback to detect "DEBUG: Running ''" debug line. + """Create a callback to detect if eventlog service is down. Args: - log_format (str): Log format of the command monitoring (full_command or command). - command (str): Command to be monitored. - prefix (str): Daemon that generates the log. - escape (bool): Flag to escape special characters in the pattern. + location (str): Event channel. + severity (str): Severity of the error (WARNING, ERROR or CRITICAL). Returns: callable: callback to detect this event. @@ -239,14 +210,13 @@ def callback_event_log_service_down(location, severity='WARNING'): log_format_message = f"{severity}: The eventlog service is down. Unable to collect logs from '{location}' channel." return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) + def callback_trying_to_reconnect(location, reconnect_time): - """Create a callback to detect "DEBUG: Running ''" debug line. + """Create a callback to detect if `wazuh-agentd` is trying to reconnect to specified channel. Args: - log_format (str): Log format of the command monitoring (full_command or command). - command (str): Command to be monitored. - prefix (str): Daemon that generates the log. - escape (bool): Flag to escape special characters in the pattern. + location (str): Event log channel. + reconnect_time (str): Reconnect time. Returns: callable: callback to detect this event. @@ -254,6 +224,7 @@ def callback_trying_to_reconnect(location, reconnect_time): log_format_message = f"DEBUG: Trying to reconnect {location} channel in {reconnect_time} seconds." return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) + def callback_reconnect_eventchannel(location): """Create a callback to detect if specified channel has been reconnected successfully. @@ -263,6 +234,8 @@ def callback_reconnect_eventchannel(location): """ log_format_message = f"INFO: '{location}' channel has been reconnected succesfully." return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX) + + def callback_match_pattern_file(file_pattern, file): """Create a callback to detect if logcollector is monitoring a file with wildcard. Args: From dbb62e213951c821876bafcc41a8ea3102d0a95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Rebollo?= Date: Mon, 10 May 2021 14:04:54 +0200 Subject: [PATCH 9/9] Add callback_reconnect_eventchannel returns documentation --- deps/wazuh_testing/wazuh_testing/logcollector.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deps/wazuh_testing/wazuh_testing/logcollector.py b/deps/wazuh_testing/wazuh_testing/logcollector.py index 1623368068..5f24476fd9 100644 --- a/deps/wazuh_testing/wazuh_testing/logcollector.py +++ b/deps/wazuh_testing/wazuh_testing/logcollector.py @@ -231,6 +231,8 @@ def callback_reconnect_eventchannel(location): Args: location (str): Location channel. + Returns: + callable: callback to detect this event. """ log_format_message = f"INFO: '{location}' channel has been reconnected succesfully." return monitoring.make_callback(pattern=log_format_message, prefix=monitoring.AGENT_DETECTOR_PREFIX)