1#!/usr/bin/env python3 2# coding=utf-8 3 4# 5# Copyright (c) 2020-2024 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import re 20from collections import namedtuple 21 22__all__ = ["Error", "ErrorCategory", "ErrorMessage"] 23 24 25class ErrorCategory: 26 Environment = "Environment" 27 Framework = "Framework" 28 Script = "Script" 29 30 31class Error(namedtuple("Error", ["code", "error", "category", "suggestions"], 32 defaults=[ErrorCategory.Framework, ""])): 33 """ 34 错误码: 35 1~2位,01-99,插件编号:01-xdevice、02-devicetest、03-ohos、... 36 3~4位,01-99,保留位,可自由分配,如将环境问题细分为hdc问题、设备问题、... 37 5~7位,000-999,错误编号 38 示例: 39 [Framework-0101123] error message [Suggestions] fix suggestions 40 解析: 41 Framework是错误类别,0101123是错误代码,error message是错误信息,Suggestions是修改建议(可选) 42 """ 43 44 __slots__ = () 45 46 def __repr__(self): 47 msg = "[{}-{}] {}".format(self.category, self.code, self.error) 48 if self.suggestions: 49 msg += " [Suggestions] {}".format(self.suggestions) 50 return msg 51 52 def format(self, *args, **kwargs): 53 # 错误出现嵌套的情况,返回原始的错误 54 for arg in args: 55 arg_str = str(arg) 56 if re.search(r'\[.*[a-zA-Z0-9]+].*(?:\[Suggestions].*)?', arg_str) is not None: 57 return arg_str 58 59 return self.__str__().format(*args, **kwargs) 60 61 62class _CommonErr: 63 """Code_0101xxx,汇总常见的、未归类的问题""" 64 Code_0101001 = Error(**{"error": "Unsupported system environment", 65 "code": "0101001"}) 66 Code_0101002 = Error(**{"error": "File path does not exist, path: {}", 67 "category": "{}", 68 "code": "0101002"}) 69 Code_0101003 = Error(**{"error": "Test kit {} does not exist", 70 "code": "0101003", 71 "suggestions": "1、kit名称错误;2、未安装kit依赖的模块"}) 72 Code_0101004 = Error(**{"error": "Test kit {} has no attribute of device_name", 73 "code": "0101004"}) 74 Code_0101005 = Error(**{"error": "History report path does not exist, path: {}", 75 "code": "0101005"}) 76 Code_0101006 = Error(**{"error": "The combined parameters which key '{}' has no value", 77 "category": ErrorCategory.Environment, 78 "code": "0101006", 79 "suggestions": "按照格式“key1:value1;key2:value2”使用组合参数"}) 80 Code_0101007 = Error(**{"error": "no retry case exists", 81 "code": "0101007"}) 82 Code_0101008 = Error(**{"error": "session '{}' is invalid", 83 "category": ErrorCategory.Environment, 84 "code": "0101008"}) 85 Code_0101009 = Error(**{"error": "no previous executed command", 86 "category": ErrorCategory.Environment, 87 "code": "0101009"}) 88 Code_0101010 = Error(**{"error": "session '{}' has no executed command", 89 "category": ErrorCategory.Environment, 90 "code": "0101010"}) 91 Code_0101011 = Error(**{"error": "wrong input task id '{}'", 92 "category": ErrorCategory.Environment, 93 "code": "0101011"}) 94 Code_0101012 = Error(**{"error": "Unsupported command action '{}'", 95 "category": ErrorCategory.Environment, 96 "code": "0101012", 97 "suggestions": "此方法用作处理run指令"}) 98 Code_0101013 = Error(**{"error": "Unsupported execution type '{}'", 99 "category": ErrorCategory.Environment, 100 "code": "0101013", 101 "suggestions": "当前支持设备测试device_test和主机测试host_test"}) 102 Code_0101014 = Error(**{"error": "Test source '{}' or its json does not exist", 103 "category": ErrorCategory.Environment, 104 "code": "0101014", 105 "suggestions": "1、确认是否存在对应的测试文件或用例json;2、检查user_config.xml的testcase路径配置;" 106 "3、确保xdevice框架程序工作目录为脚本工程目录"}) 107 Code_0101015 = Error(**{"error": "Task file does not exist, file name: {}", 108 "category": ErrorCategory.Environment, 109 "code": "0101015", 110 "suggestions": "需将任务json放在config目录下。如run acts全量运行acts测试用例," 111 "需将acts.json放在config目录下"}) 112 Code_0101016 = Error(**{"error": "No test driver to execute", 113 "category": ErrorCategory.Script, 114 "code": "0101016", 115 "suggestions": "用例json需要配置测试驱动"}) 116 Code_0101017 = Error(**{"error": "Test source '{}' has no test driver specified", 117 "category": ErrorCategory.Environment, 118 "code": "0101017", 119 "suggestions": "用例json需要配置测试驱动"}) 120 Code_0101018 = Error(**{"error": "Test source '{}' can't find the specified test driver '{}'", 121 "category": ErrorCategory.Environment, 122 "code": "0101018", 123 "suggestions": "1、用例json驱动名称填写错误;2、驱动插件未安装"}) 124 Code_0101019 = Error(**{"error": "Test source '{}' can't find the suitable test driver '{}'", 125 "category": ErrorCategory.Environment, 126 "code": "0101019", 127 "suggestions": "1、用例json驱动名称填写错误;2、驱动插件未安装"}) 128 Code_0101020 = Error(**{"error": "report path must be an empty folder", 129 "category": ErrorCategory.Environment, 130 "code": "0101020", 131 "suggestions": "测试报告路径需为一个空文件夹"}) 132 Code_0101021 = Error(**{"error": "Test source required {} devices, actually {} devices were found", 133 "category": ErrorCategory.Environment, 134 "code": "0101021", 135 "suggestions": "测试用例的设备条件不满足"}) 136 Code_0101022 = Error(**{"error": "no test file, list, dict, case or task were found", 137 "category": ErrorCategory.Environment, 138 "code": "0101022", 139 "suggestions": "未发现用例"}) 140 Code_0101023 = Error(**{"error": "test source is none", 141 "category": ErrorCategory.Script, 142 "code": "0101023"}) 143 Code_0101024 = Error(**{"error": "Test file '{}' does not exist", 144 "category": ErrorCategory.Environment, 145 "code": "0101024"}) 146 Code_0101025 = Error(**{"error": "RSA encryption error occurred, {}", 147 "code": "0101025"}) 148 Code_0101026 = Error(**{"error": "RSA decryption error occurred, {}", 149 "code": "0101026"}) 150 Code_0101027 = Error(**{"error": "Json file does not exist, file: {}", 151 "code": "0101027"}) 152 Code_0101028 = Error(**{"error": "Json file load error, file: {}, error: {}", 153 "category": ErrorCategory.Script, 154 "code": "0101028"}) 155 Code_0101029 = Error(**{"error": "'{}' under '{}' should be dict", 156 "category": ErrorCategory.Script, 157 "code": "0101029"}) 158 Code_0101030 = Error(**{"error": "'type' key does not exist in '{}' under '{}'", 159 "category": ErrorCategory.Script, 160 "code": "0101030"}) 161 Code_0101031 = Error(**{"error": "The parameter {} {} is error", 162 "category": ErrorCategory.Environment, 163 "code": "0101031"}) 164 165 166class _InterfaceImplementErr: 167 """Code_0102xxx,汇总接口实现的问题""" 168 Code_0102001 = Error(**{"error": "@Plugin must be specify type and id attributes. such as @Plugin('plugin_type') " 169 "or @Plugin(type='plugin_type', id='plugin_id')", 170 "code": "0102001"}) 171 Code_0102002 = Error(**{"error": "'{}' attribute is not allowed for plugin {}", 172 "code": "0102002"}) 173 Code_0102003 = Error(**{"error": "__init__ method must be no arguments for plugin {}", 174 "code": "0102003"}) 175 Code_0102004 = Error(**{"error": "'{}' method is not allowed for plugin {}", 176 "code": "0102004"}) 177 Code_0102005 = Error(**{"error": "{} plugin must be implement as {}", 178 "code": "0102005"}) 179 Code_0102006 = Error(**{"error": "Can not find the plugin {}", 180 "code": "0102006"}) 181 Code_0102007 = Error(**{"error": "Parser {} must be implement as IParser", 182 "code": "0102007"}) 183 184 185class _UserConfigErr: 186 """Code_0103xxx,汇总user_config.xml配置有误的问题""" 187 Code_0103001 = Error(**{"error": "user_config.xml does not exist", 188 "category": ErrorCategory.Environment, 189 "code": "0103001", 190 "suggestions": "1、确保框架程序运行目录为工程根目录;2、工程根目录存在配置文件config/user_config.xml"}) 191 Code_0103002 = Error(**{"error": "Parsing the user_config.xml failed, error: {}", 192 "category": ErrorCategory.Environment, 193 "code": "0103002", 194 "suggestions": "检查user_config.xml配置文件的格式"}) 195 Code_0103003 = Error(**{"error": "Parsing the user_config.xml from parameter(-env) failed, error: {}", 196 "category": ErrorCategory.Environment, 197 "code": "0103003", 198 "suggestions": "检查-env运行参数配置内容的格式"}) 199 Code_0103004 = Error(**{"error": "The alias of device {} is the same as that of device {}", 200 "category": ErrorCategory.Environment, 201 "code": "0103004", 202 "suggestions": "设备别名不允许同名"}) 203 204 205class _Cluster: 206 """Code_0104xxx,cluster模块使用的错误码""" 207 Code_0104001 = Error(**{"error": "cluster.control_service_url cannot be none", 208 "category": ErrorCategory.Environment, 209 "code": "0104001"}) 210 Code_0104002 = Error(**{"error": "Unsupported project manage mode '{}'", 211 "category": ErrorCategory.Environment, 212 "code": "0104002"}) 213 Code_0104003 = Error(**{"error": "The project path does not exist! path: {}", 214 "category": ErrorCategory.Environment, 215 "code": "0104003"}) 216 Code_0104004 = Error(**{"error": "The configured project relative path does not exist! path: {}", 217 "category": ErrorCategory.Environment, 218 "code": "0104004"}) 219 Code_0104005 = Error(**{"error": "The git url cannot be empty", 220 "category": ErrorCategory.Environment, 221 "code": "0104005"}) 222 Code_0104006 = Error(**{"error": "The git username cannot be empty", 223 "category": ErrorCategory.Environment, 224 "code": "0104006"}) 225 Code_0104007 = Error(**{"error": "The git password cannot be empty", 226 "category": ErrorCategory.Environment, 227 "code": "0104007"}) 228 Code_0104008 = Error(**{"error": "The git branch cannot be empty", 229 "category": ErrorCategory.Environment, 230 "code": "0104008"}) 231 Code_0104009 = Error(**{"error": "Non-HTTP git url is not supported, url: {}", 232 "category": ErrorCategory.Environment, 233 "code": "0104009"}) 234 Code_0104010 = Error(**{"error": "Prepare git project failed", 235 "category": ErrorCategory.Environment, 236 "code": "0104010"}) 237 Code_0104011 = Error(**{"error": "The svn url cannot be empty", 238 "category": ErrorCategory.Environment, 239 "code": "0104011"}) 240 Code_0104012 = Error(**{"error": "The svn username cannot be empty", 241 "category": ErrorCategory.Environment, 242 "code": "0104012"}) 243 Code_0104013 = Error(**{"error": "The svn password cannot be empty", 244 "category": ErrorCategory.Environment, 245 "code": "0104013"}) 246 Code_0104014 = Error(**{"error": "Prepare svn project failed, {}", 247 "category": ErrorCategory.Environment, 248 "code": "0104014"}) 249 Code_0104015 = Error(**{"error": "The downloaded file url cannot be empty", 250 "category": ErrorCategory.Environment, 251 "code": "0104015"}) 252 Code_0104016 = Error(**{"error": "Download file failed, {}", 253 "category": ErrorCategory.Environment, 254 "code": "0104016"}) 255 Code_0104017 = Error(**{"error": "Download file failed because the downloaded file is incomplete", 256 "category": ErrorCategory.Environment, 257 "code": "0104017"}) 258 Code_0104018 = Error(**{"error": "Extract file failed, file: {}", 259 "category": ErrorCategory.Environment, 260 "code": "0104018"}) 261 Code_0104019 = Error(**{"error": "用例需要{}个测试设备,所有worker环境上的在线设备数量均小于用例测试设备需求数量", 262 "category": ErrorCategory.Environment, 263 "code": "0104019"}) 264 Code_0104020 = Error(**{"error": "所有worker环境上在线的设备均不满足用例的要求", 265 "category": ErrorCategory.Environment, 266 "code": "0104020"}) 267 Code_0104021 = Error(**{"error": "用例json未配置environment,或配置的environment为空", 268 "category": ErrorCategory.Script, 269 "code": "0104021"}) 270 Code_0104022 = Error(**{"error": "无法运行{}命令", 271 "category": ErrorCategory.Environment, 272 "code": "0104022", 273 "suggestions": "未配置工具的环境变量"}) 274 Code_0104023 = Error(**{"error": "zipfile({}) contains {} files exceed max file count", 275 "category": ErrorCategory.Environment, 276 "code": "0104023", 277 "suggestions": "不支持解压文件总个数超过100万的zip压缩包"}) 278 Code_0104024 = Error(**{"error": "zipfile({}) size({}) exceed max limit", 279 "category": ErrorCategory.Environment, 280 "code": "0104024", 281 "suggestions": "不支持解压文件总大小超过5GB的zip压缩包"}) 282 Code_0104025 = Error(**{"error": "zipfile({}) size({}) exceed remain target disk space", 283 "category": ErrorCategory.Environment, 284 "code": "0104025", 285 "suggestions": "压缩文件总大小超过磁盘剩余空间"}) 286 Code_0104026 = Error(**{"error": "To use the cluster test service, upgrade Python to 3.10 or later", 287 "category": ErrorCategory.Environment, 288 "code": "0104026", 289 "suggestions": "使用cluster测试服务,需将Python升级到3.8及之后的版本"}) 290 Code_0104027 = Error(**{"error": "failed to create the controller task because the " 291 "task template file does not exist, path: {}", 292 "category": ErrorCategory.Environment, 293 "code": "0104027"}) 294 Code_0104028 = Error(**{"error": "failed to create the controller task because the " 295 "task template info is not validated", 296 "category": ErrorCategory.Environment, 297 "code": "0104028"}) 298 Code_0104029 = Error(**{"error": "create the controller task failed, {}", 299 "category": ErrorCategory.Environment, 300 "code": "0104029"}) 301 Code_0104030 = Error(**{"error": "get controller devices failed, {}", 302 "category": ErrorCategory.Environment, 303 "code": "0104030"}) 304 Code_0104031 = Error(**{"error": "get controller task(s) failed, {}", 305 "category": ErrorCategory.Environment, 306 "code": "0104031"}) 307 Code_0104032 = Error(**{"error": "report worker device failed, {}", 308 "category": ErrorCategory.Environment, 309 "code": "0104032"}) 310 Code_0104033 = Error(**{"error": "upload task end failed, {}", 311 "category": ErrorCategory.Environment, 312 "code": "0104033"}) 313 Code_0104034 = Error(**{"error": "No device in task info", 314 "category": ErrorCategory.Environment, 315 "code": "0104034"}) 316 317 318class ErrorMessage: 319 Common: _CommonErr = _CommonErr() 320 InterfaceImplement: _InterfaceImplementErr = _InterfaceImplementErr() 321 UserConfig: _UserConfigErr = _UserConfigErr() 322 Cluster: _Cluster = _Cluster() 323 324 325if __name__ == "__main__": 326 # 用法1,使用原始类,无需格式化报错内容 327 _err_101 = Error(**{"error": "error 101", "code": "101"}) 328 print(_err_101) 329 330 # 用法2,使用构造方法,按format格式化报错内容 331 _err_102 = Error(**{"error": "{}, path: {}", "code": "102", "suggestions": "sss"}) 332 print(_err_102.format("error 102", "test path")) 333 print(_err_102.code) 334 335 # 测试错误嵌套的情况 336 # 如:[Framework-102] [Framework-102] error 102, path: test path [Suggestions] sss, path: test path [Suggestions] sss 337 err_msg1 = "[Framework-102] error 102, path: test path" 338 print(_err_102.format(err_msg1, "test path1")) 339 err_msg1 = "[Framework-102] error 102, path: test path [Suggestions] sss" 340 print(_err_102.format(err_msg1, "test path2")) 341