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 severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR 66 67 def __init__(self, host: str): 68 self.host = host 69 70 def __str__(self) -> str: 71 return f"Error trying to connect with {self.host}" 72 73 74class SSHSessionDeadError(DTSError): 75 """ 76 SSH session is not alive. 77 It can no longer be used. 78 """ 79 80 host: str 81 severity: ClassVar[ErrorSeverity] = ErrorSeverity.SSH_ERR 82 83 def __init__(self, host: str): 84 self.host = host 85 86 def __str__(self) -> str: 87 return f"SSH session with {self.host} has died" 88 89 90class ConfigurationError(DTSError): 91 """ 92 Raised when an invalid configuration is encountered. 93 """ 94 95 severity: ClassVar[ErrorSeverity] = ErrorSeverity.CONFIG_ERR 96 97 98class RemoteCommandExecutionError(DTSError): 99 """ 100 Raised when a command executed on a Node returns a non-zero exit status. 101 """ 102 103 command: str 104 command_return_code: int 105 severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR 106 107 def __init__(self, command: str, command_return_code: int): 108 self.command = command 109 self.command_return_code = command_return_code 110 111 def __str__(self) -> str: 112 return ( 113 f"Command {self.command} returned a non-zero exit code: " 114 f"{self.command_return_code}" 115 ) 116 117 118class RemoteDirectoryExistsError(DTSError): 119 """ 120 Raised when a remote directory to be created already exists. 121 """ 122 123 severity: ClassVar[ErrorSeverity] = ErrorSeverity.REMOTE_CMD_EXEC_ERR 124 125 126class DPDKBuildError(DTSError): 127 """ 128 Raised when DPDK build fails for any reason. 129 """ 130 131 severity: ClassVar[ErrorSeverity] = ErrorSeverity.DPDK_BUILD_ERR 132 133 134class TestCaseVerifyError(DTSError): 135 """ 136 Used in test cases to verify the expected behavior. 137 """ 138 139 value: str 140 severity: ClassVar[ErrorSeverity] = ErrorSeverity.TESTCASE_VERIFY_ERR 141 142 def __init__(self, value: str): 143 self.value = value 144 145 def __str__(self) -> str: 146 return repr(self.value) 147