xref: /dpdk/dts/framework/exception.py (revision 00e57b0e550b7df2047e6d0bde8965c7ae17d203)
1# SPDX-License-Identifier: BSD-3-Clause
2# Copyright(c) 2010-2014 Intel Corporation
3# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
4# Copyright(c) 2022-2023 University of New Hampshire
5
6"""
7User-defined exceptions used across the framework.
8"""
9
10from enum import IntEnum, unique
11from typing import ClassVar
12
13
14@unique
15class ErrorSeverity(IntEnum):
16    """
17    The severity of errors that occur during DTS execution.
18    All exceptions are caught and the most severe error is used as return code.
19    """
20
21    NO_ERR = 0
22    GENERIC_ERR = 1
23    CONFIG_ERR = 2
24    REMOTE_CMD_EXEC_ERR = 3
25    SSH_ERR = 4
26    DPDK_BUILD_ERR = 10
27    TESTCASE_VERIFY_ERR = 20
28
29
30class DTSError(Exception):
31    """
32    The base exception from which all DTS exceptions are derived.
33    Stores error severity.
34    """
35
36    severity: ClassVar[ErrorSeverity] = ErrorSeverity.GENERIC_ERR
37
38
39class SSHTimeoutError(DTSError):
40    """
41    Command execution timeout.
42    """
43
44    command: str
45    output: str
46    severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
47
48    def __init__(self, command: str, output: str):
49        self.command = command
50        self.output = output
51
52    def __str__(self) -> str:
53        return f"TIMEOUT on {self.command}"
54
55    def get_output(self) -> str:
56        return self.output
57
58
59class SSHConnectionError(DTSError):
60    """
61    SSH connection error.
62    """
63
64    host: str
65    errors: list[str]
66    severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
67
68    def __init__(self, host: str, errors: list[str] | None = None):
69        self.host = host
70        self.errors = [] if errors is None else errors
71
72    def __str__(self) -> str:
73        message = f"Error trying to connect with {self.host}."
74        if self.errors:
75            message += f" Errors encountered while retrying: {', '.join(self.errors)}"
76
77        return message
78
79
80class SSHSessionDeadError(DTSError):
81    """
82    SSH session is not alive.
83    It can no longer be used.
84    """
85
86    host: str
87    severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR
88
89    def __init__(self, host: str):
90        self.host = host
91
92    def __str__(self) -> str:
93        return f"SSH session with {self.host} has died"
94
95
96class ConfigurationError(DTSError):
97    """
98    Raised when an invalid configuration is encountered.
99    """
100
101    severity: ClassVar[ErrorSeverity] = ErrorSeverity.CONFIG_ERR
102
103
104class RemoteCommandExecutionError(DTSError):
105    """
106    Raised when a command executed on a Node returns a non-zero exit status.
107    """
108
109    command: str
110    command_return_code: int
111    severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR
112
113    def __init__(self, command: str, command_return_code: int):
114        self.command = command
115        self.command_return_code = command_return_code
116
117    def __str__(self) -> str:
118        return (
119            f"Command {self.command} returned a non-zero exit code: "
120            f"{self.command_return_code}"
121        )
122
123
124class RemoteDirectoryExistsError(DTSError):
125    """
126    Raised when a remote directory to be created already exists.
127    """
128
129    severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR
130
131
132class DPDKBuildError(DTSError):
133    """
134    Raised when DPDK build fails for any reason.
135    """
136
137    severity: ClassVar[ErrorSeverity] = ErrorSeverity.DPDK_BUILD_ERR
138
139
140class TestCaseVerifyError(DTSError):
141    """
142    Used in test cases to verify the expected behavior.
143    """
144
145    value: str
146    severity: ClassVar[ErrorSeverity] = ErrorSeverity.TESTCASE_VERIFY_ERR
147
148    def __init__(self, value: str):
149        self.value = value
150
151    def __str__(self) -> str:
152        return repr(self.value)
153