From c130d3f1151d3b914d0f457b487b192e9c7dfe9e Mon Sep 17 00:00:00 2001 From: croy Date: Fri, 17 Oct 2025 14:08:29 -0400 Subject: [PATCH] Adding testcase_log_index to logger_config In order to avoid conflicts with folder names when rerunning a test case, we add testcase_log_index to the logger_config and use it to tag a number next to each result folder. e.g. 001_test_case 002_test_second Change-Id: I6b727f183a7d772e7cdce9c4f9f78c723c993076 Signed-off-by: croy --- config/logger/files/default.json5 | 2 +- config/logger/objects/logger_config.py | 53 +++++++++++++++++--------- framework/logging/automation_logger.py | 9 ++++- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/config/logger/files/default.json5 b/config/logger/files/default.json5 index f28e5102..4a0aaa9d 100644 --- a/config/logger/files/default.json5 +++ b/config/logger/files/default.json5 @@ -7,6 +7,6 @@ // Acceptable values are: ERROR, WARNING, INFO, or DEBUG "console_log_level": "DEBUG", // Level of Logs displayed in the console. "file_log_level": "DEBUG", // Level of Logs included in log files. - + "testcase_log_index": 1 // Starting index for test case folder numbering (optional, defaults to 1) } \ No newline at end of file diff --git a/config/logger/objects/logger_config.py b/config/logger/objects/logger_config.py index 67d3e362..004e6a78 100644 --- a/config/logger/objects/logger_config.py +++ b/config/logger/objects/logger_config.py @@ -21,9 +21,9 @@ class LoggerConfig: log_dict = json5.load(json_data) # If it is left as "DEFAULT", then "~/AUTOMATION_LOGS" will be used - self.log_location = log_dict['log_location'] + self.log_location = log_dict["log_location"] if self.log_location == "DEFAULT": - home_dir = os.path.expanduser('~') + home_dir = os.path.expanduser("~") subfolder = "AUTOMATION_LOGS" self.log_location = os.path.join(home_dir, subfolder) @@ -36,35 +36,38 @@ class LoggerConfig: "WARNING": logging.WARNING, "ERROR": logging.ERROR, } - self.console_log_level = log_dict['console_log_level'] + self.console_log_level = log_dict["console_log_level"] if self.console_log_level not in log_levels_map: raise ValueError(f"The provided Console Log Level is invalid. " f"Please select a value in {log_levels_map.keys()}.") self.console_log_level_value = log_levels_map[self.console_log_level] - self.file_log_level = log_dict['file_log_level'] + self.file_log_level = log_dict["file_log_level"] if self.file_log_level not in log_levels_map: raise ValueError(f"The provided File Log Level is invalid. " f"Please select a value in {log_levels_map.keys()}.") self.file_log_level_value = log_levels_map[self.file_log_level] self.append_lab_and_timestamp = True - if 'append_lab_and_timestamp' in log_dict: - self.append_lab_and_timestamp = log_dict['append_lab_and_timestamp'] + if "append_lab_and_timestamp" in log_dict: + self.append_lab_and_timestamp = log_dict["append_lab_and_timestamp"] + + self.testcase_log_index = 1 + if "testcase_log_index" in log_dict: + self.testcase_log_index = log_dict["testcase_log_index"] def get_log_location(self) -> str: """ Getter for the folder where we want to store the log files. - Returns: the path to the folder where we want to store the log files. + Returns: the path to the folder where we want to store the log files. """ return self.log_location def get_test_case_resources_log_location(self) -> str: """ Getter for the folder where we store resource files used by a test case. + Returns: the path to the folder where we want to store the resource files used by a test case. - """ - if not self.test_case_resources_log_location: self.test_case_resources_log_location = os.path.join(self.get_log_location(), "resources") os.makedirs(self.test_case_resources_log_location, exist_ok=True) @@ -74,48 +77,62 @@ class LoggerConfig: def get_console_log_level(self) -> str: """ Getter for the console log level as a readable String representation. - Returns: The console log level that is currently set. + Returns: The console log level that is currently set. """ return self.console_log_level def get_console_log_level_value(self) -> str: """ - Getter for the console log level value which is used to configure the logger - Returns: The console log level that is currently set. + Getter for the console log level value which is used to configure the logger. + Returns: The console log level that is currently set. """ return self.console_log_level_value def get_file_log_level(self) -> str: """ Getter for the file log level as a readable String representation. - Returns: The file log level that is currently set. + Returns: The file log level that is currently set. """ return self.file_log_level def get_file_log_level_value(self) -> str: """ - Getter for the file log level value which is used to configure the logger - Returns: The file log level that is currently set. + Getter for the file log level value which is used to configure the logger. + Returns: The file log level that is currently set. """ return self.file_log_level_value def get_append_lab_and_timestamp(self) -> bool: """ - Getter to see if we should append lab name and timestamp folders to the log file location - Returns: + Getter to see if we should append lab name and timestamp folders to the log file location. + Returns: Boolean indicating if lab name and timestamp should be appended. """ return self.append_lab_and_timestamp + def get_testcase_log_index(self) -> int: + """ + Getter for the current test case log index. + + Returns: The current test case log index. + """ + return self.testcase_log_index + + def increment_testcase_log_index(self) -> None: + """ + Increment the test case log index. + """ + self.testcase_log_index += 1 + def to_log_strings(self) -> List[str]: """ This function will return a list of strings that can be logged to show all the logger configs. - Returns: A List of strings to be sent to the logger. + Returns: A List of strings to be sent to the logger. """ log_strings = [] log_strings.append(f"log_location: {self.get_log_location()}") diff --git a/framework/logging/automation_logger.py b/framework/logging/automation_logger.py index 9e9533e0..b60808d0 100644 --- a/framework/logging/automation_logger.py +++ b/framework/logging/automation_logger.py @@ -276,8 +276,13 @@ def configure_testcase_log_handler(logger_config: LoggerConfig, log_file: str) - logger_config (LoggerConfig): The logger config. log_file (str): The log file name. """ + # Get current index and increment for next test case + folder_number = logger_config.get_testcase_log_index() + logger_config.increment_testcase_log_index() + numbered_folder_name = f"{folder_number:03d}_{log_file}" + log_formatter = logging.Formatter(_LOGGER.GENERAL_LOGGER_FORMAT, datefmt="%Y-%m-%d %H:%M:%S") - _LOGGER.test_case_log_dir = os.path.join(_LOGGER.get_log_folder(), f"{log_file}") + _LOGGER.test_case_log_dir = os.path.join(_LOGGER.get_log_folder(), numbered_folder_name) os.makedirs(_LOGGER.test_case_log_dir, exist_ok=True) full_log_file_path = os.path.join(_LOGGER.test_case_log_dir, "log.txt") @@ -303,7 +308,7 @@ def remove_testcase_handler(test_name: str) -> None: test_name (str): The test name whose log handler should be removed. """ for handler in _LOGGER.handlers: - if hasattr(handler, "baseFilename") and f"{test_name}" in handler.baseFilename: + if hasattr(handler, "baseFilename") and test_name in handler.baseFilename: _LOGGER.removeHandler(handler)