f-stack/dpdk/dts/framework/exception.py

162 lines
3.9 KiB
Python

# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
# Copyright(c) 2022-2023 University of New Hampshire
"""
User-defined exceptions used across the framework.
"""
from enum import IntEnum, unique
from typing import ClassVar
@unique
class ErrorSeverity(IntEnum):
"""
The severity of errors that occur during DTS execution.
All exceptions are caught and the most severe error is used as return code.
"""
NO_ERR = 0
GENERIC_ERR = 1
CONFIG_ERR = 2
REMOTE_CMD_EXEC_ERR = 3
SSH_ERR = 4
DPDK_BUILD_ERR = 10
TESTCASE_VERIFY_ERR = 20
BLOCKING_TESTSUITE_ERR = 25
class DTSError(Exception):
"""
The base exception from which all DTS exceptions are derived.
Stores error severity.
"""
severity: ClassVar[ErrorSeverity] = ErrorSeverity.GENERIC_ERR
class SSHTimeoutError(DTSError):
"""
Command execution timeout.
"""
command: str
output: str
severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
def __init__(self, command: str, output: str):
self.command = command
self.output = output
def __str__(self) -> str:
return f"TIMEOUT on {self.command}"
def get_output(self) -> str:
return self.output
class SSHConnectionError(DTSError):
"""
SSH connection error.
"""
host: str
errors: list[str]
severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
def __init__(self, host: str, errors: list[str] | None = None):
self.host = host
self.errors = [] if errors is None else errors
def __str__(self) -> str:
message = f"Error trying to connect with {self.host}."
if self.errors:
message += f" Errors encountered while retrying: {', '.join(self.errors)}"
return message
class SSHSessionDeadError(DTSError):
"""
SSH session is not alive.
It can no longer be used.
"""
host: str
severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
def __init__(self, host: str):
self.host = host
def __str__(self) -> str:
return f"SSH session with {self.host} has died"
class ConfigurationError(DTSError):
"""
Raised when an invalid configuration is encountered.
"""
severity: ClassVar[ErrorSeverity] = ErrorSeverity.CONFIG_ERR
class RemoteCommandExecutionError(DTSError):
"""
Raised when a command executed on a Node returns a non-zero exit status.
"""
command: str
command_return_code: int
severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR
def __init__(self, command: str, command_return_code: int):
self.command = command
self.command_return_code = command_return_code
def __str__(self) -> str:
return f"Command {self.command} returned a non-zero exit code: {self.command_return_code}"
class RemoteDirectoryExistsError(DTSError):
"""
Raised when a remote directory to be created already exists.
"""
severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR
class DPDKBuildError(DTSError):
"""
Raised when DPDK build fails for any reason.
"""
severity: ClassVar[ErrorSeverity] = ErrorSeverity.DPDK_BUILD_ERR
class TestCaseVerifyError(DTSError):
"""
Used in test cases to verify the expected behavior.
"""
value: str
severity: ClassVar[ErrorSeverity] = ErrorSeverity.TESTCASE_VERIFY_ERR
def __init__(self, value: str):
self.value = value
def __str__(self) -> str:
return repr(self.value)
class BlockingTestSuiteError(DTSError):
suite_name: str
severity: ClassVar[ErrorSeverity] = ErrorSeverity.BLOCKING_TESTSUITE_ERR
def __init__(self, suite_name: str) -> None:
self.suite_name = suite_name
def __str__(self) -> str:
return f"Blocking suite {self.suite_name} failed."