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 <Christian.Roy@windriver.com>
This commit is contained in:
croy
2025-10-17 14:08:29 -04:00
committed by Christian Roy
parent 2f133194af
commit c130d3f115
3 changed files with 43 additions and 21 deletions

View File

@@ -7,6 +7,6 @@
// Acceptable values are: ERROR, WARNING, INFO, or DEBUG // Acceptable values are: ERROR, WARNING, INFO, or DEBUG
"console_log_level": "DEBUG", // Level of Logs displayed in the console. "console_log_level": "DEBUG", // Level of Logs displayed in the console.
"file_log_level": "DEBUG", // Level of Logs included in log files. "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)
} }

View File

@@ -21,9 +21,9 @@ class LoggerConfig:
log_dict = json5.load(json_data) log_dict = json5.load(json_data)
# If it is left as "DEFAULT", then "~/AUTOMATION_LOGS" will be used # 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": if self.log_location == "DEFAULT":
home_dir = os.path.expanduser('~') home_dir = os.path.expanduser("~")
subfolder = "AUTOMATION_LOGS" subfolder = "AUTOMATION_LOGS"
self.log_location = os.path.join(home_dir, subfolder) self.log_location = os.path.join(home_dir, subfolder)
@@ -36,35 +36,38 @@ class LoggerConfig:
"WARNING": logging.WARNING, "WARNING": logging.WARNING,
"ERROR": logging.ERROR, "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: 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()}.") 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.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: 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()}.") 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.file_log_level_value = log_levels_map[self.file_log_level]
self.append_lab_and_timestamp = True self.append_lab_and_timestamp = True
if 'append_lab_and_timestamp' in log_dict: if "append_lab_and_timestamp" in log_dict:
self.append_lab_and_timestamp = log_dict['append_lab_and_timestamp'] 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: def get_log_location(self) -> str:
""" """
Getter for the folder where we want to store the log files. 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 return self.log_location
def get_test_case_resources_log_location(self) -> str: def get_test_case_resources_log_location(self) -> str:
""" """
Getter for the folder where we store resource files used by a test case. 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. 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: if not self.test_case_resources_log_location:
self.test_case_resources_log_location = os.path.join(self.get_log_location(), "resources") 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) os.makedirs(self.test_case_resources_log_location, exist_ok=True)
@@ -74,48 +77,62 @@ class LoggerConfig:
def get_console_log_level(self) -> str: def get_console_log_level(self) -> str:
""" """
Getter for the console log level as a readable String representation. 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 return self.console_log_level
def get_console_log_level_value(self) -> str: def get_console_log_level_value(self) -> str:
""" """
Getter for the console log level value which is used to configure the logger Getter for the console log level value which is used to configure the logger.
Returns: The console log level that is currently set.
Returns: The console log level that is currently set.
""" """
return self.console_log_level_value return self.console_log_level_value
def get_file_log_level(self) -> str: def get_file_log_level(self) -> str:
""" """
Getter for the file log level as a readable String representation. 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 return self.file_log_level
def get_file_log_level_value(self) -> str: def get_file_log_level_value(self) -> str:
""" """
Getter for the file log level value which is used to configure the logger Getter for the file log level value which is used to configure the logger.
Returns: The file log level that is currently set.
Returns: The file log level that is currently set.
""" """
return self.file_log_level_value return self.file_log_level_value
def get_append_lab_and_timestamp(self) -> bool: 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 Getter to see if we should append lab name and timestamp folders to the log file location.
Returns:
Returns: Boolean indicating if lab name and timestamp should be appended.
""" """
return self.append_lab_and_timestamp 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]: 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. 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 = []
log_strings.append(f"log_location: {self.get_log_location()}") log_strings.append(f"log_location: {self.get_log_location()}")

View File

@@ -276,8 +276,13 @@ def configure_testcase_log_handler(logger_config: LoggerConfig, log_file: str) -
logger_config (LoggerConfig): The logger config. logger_config (LoggerConfig): The logger config.
log_file (str): The log file name. 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") 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) os.makedirs(_LOGGER.test_case_log_dir, exist_ok=True)
full_log_file_path = os.path.join(_LOGGER.test_case_log_dir, "log.txt") 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. test_name (str): The test name whose log handler should be removed.
""" """
for handler in _LOGGER.handlers: 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) _LOGGER.removeHandler(handler)