1#!/usr/bin/env python3 2# coding=utf-8 3 4# 5# Copyright (c) 2020 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 argparse 20import sys 21import signal 22import platform 23 24from core.constants import ToolCommandType 25from xdevice import platform_logger 26from xdevice import EnvironmentManager 27from core.command.run import Run 28from core.command.gen import Gen 29from core.command.display import display_help_info 30from core.command.display import display_show_info 31from core.command.display import show_wizard_mode 32from core.config.config_manager import UserConfigManager 33from core.utils import is_lite_product 34 35try: 36 if platform.system() != 'Windows': 37 import readline 38except ModuleNotFoundError: 39 print("ModuleNotFoundError: readline module is not exist.") 40except ImportError: 41 print("ImportError: libreadline.so is not exist.") 42 43__all__ = ["Console"] 44LOG = platform_logger("Console") 45 46 47############################################################################## 48############################################################################## 49 50 51class Console(object): 52 """ 53 Class representing an console for executing test. 54 Main xDevice console providing user with the interface to interact 55 """ 56 __instance = None 57 wizard_dic = {} 58 59 def __new__(cls, *args, **kwargs): 60 if cls.__instance is None: 61 cls.__instance = super(Console, cls).__new__(cls, *args, **kwargs) 62 return cls.__instance 63 64 def __init__(self): 65 pass 66 67 def handler_ctrl_c(self, signalnum, frame): 68 pass 69 70 def handler_ctrl_z(self, signalnum, frame): 71 pass 72 73 def console(self, args): 74 """ 75 Main xDevice console providing user with the interface to interact 76 """ 77 EnvironmentManager() 78 if args is None or len(args) < 2: 79 self.wizard_dic = show_wizard_mode() 80 print(self.wizard_dic) 81 if self._build_version(self.wizard_dic["productform"]): 82 self._console() 83 else: 84 LOG.error("Build version failed, exit test framework.") 85 else: 86 self.command_parser(" ".join(args[1:])) 87 88 def _console(self): 89 if platform.system() != 'Windows': 90 signal.signal(signal.SIGTSTP, self.handler_ctrl_z) # ctrl+x linux 91 signal.signal(signal.SIGINT, self.handler_ctrl_c) # ctrl+c 92 93 while True: 94 try: 95 usr_input = input(">>> ") 96 if usr_input == "": 97 continue 98 self.command_parser(usr_input) 99 except SystemExit: 100 LOG.info("Program exit normally!") 101 return 102 except (IOError, EOFError, KeyboardInterrupt) as error: 103 LOG.exception("Input Error: %s" % error) 104 105 @classmethod 106 def argument_parser(cls, para_list): 107 """ 108 argument parser 109 """ 110 options = None 111 unparsed = [] 112 valid_param = True 113 parser = None 114 115 try: 116 parser = argparse.ArgumentParser(description="Specify test para.") 117 parser.add_argument("action", type=str.lower, 118 help="Specify action") 119 120 # Developer test general test parameters 121 parser.add_argument("-p", "--productform", 122 action="store", 123 type=str.lower, 124 dest="productform", 125 default="phone", 126 help="Specified product form" 127 ) 128 parser.add_argument("-t", "--testtype", 129 nargs='*', 130 type=str.upper, 131 dest="testtype", 132 default=["UT"], 133 help="Specify test type(UT,MST,ST,PERF,ALL)" 134 ) 135 parser.add_argument("-ss", "--subsystem", 136 nargs='*', 137 dest="subsystem", 138 default=[], 139 help="Specify test subsystem" 140 ) 141 parser.add_argument("-tp", "--testpart", 142 nargs='*', 143 dest="testpart", 144 default=[], 145 help="Specify test testpart" 146 ) 147 parser.add_argument("-tm", "--testmodule", 148 action="store", 149 type=str, 150 dest="testmodule", 151 default="", 152 help="Specified test module" 153 ) 154 parser.add_argument("-ts", "--testsuit", 155 action="store", 156 type=str, 157 dest="testsuit", 158 default="", 159 help="Specify test suit" 160 ) 161 parser.add_argument("-tc", "--testcase", 162 action="store", 163 type=str, 164 dest="testcase", 165 default="", 166 help="Specify test case" 167 ) 168 parser.add_argument("-tl", "--testlevel", 169 action="store", 170 type=str, 171 dest="testlevel", 172 default="", 173 help="Specify test level" 174 ) 175 176 # Developer test extended test parameters 177 parser.add_argument("-cov", "--coverage", 178 action="store_true", 179 dest="coverage", 180 default=False, 181 help="Specify coverage" 182 ) 183 parser.add_argument("-tf", "--testfile", 184 action="store", 185 type=str, 186 dest="testfile", 187 default="", 188 help="Specify test suites list file" 189 ) 190 parser.add_argument("-res", "--resource", 191 action="store", 192 type=str, 193 dest="resource", 194 default="", 195 help="Specify test resource" 196 ) 197 parser.add_argument("-dp", "--dirpath", 198 action="store", 199 type=str, 200 dest="dirpath", 201 default="", 202 help="Specify fuzz test dirpath" 203 ) 204 parser.add_argument("-fn", "--fuzzername", 205 action="store", 206 type=str, 207 dest="fuzzername", 208 default="", 209 help="Specify fuzzer name" 210 ) 211 (options, unparsed) = parser.parse_known_args(para_list) 212 213 # Set default value 214 options.target_os_name = "OHOS" 215 options.build_variant = "release" 216 options.device_sn = "" 217 options.config = "" 218 options.reportpath = "" 219 options.exectype = "device" 220 options.testdriver = "" 221 222 except SystemExit: 223 valid_param = False 224 parser.print_help() 225 LOG.warning("Parameter parsing systemexit exception.") 226 227 return options, unparsed, valid_param 228 229 def command_parser(self, args): 230 try: 231 para_list = args.split() 232 options, _, valid_param = self.argument_parser(para_list) 233 if options is None or not valid_param: 234 LOG.warning("options is None.") 235 return 236 237 command = options.action 238 if command == "": 239 LOG.warning("action is empty.") 240 return 241 242 if "productform" in self.wizard_dic.keys(): 243 productform = self.wizard_dic["productform"] 244 options.productform = productform 245 else: 246 productform = options.productform 247 248 if command.startswith(ToolCommandType.TOOLCMD_KEY_HELP): 249 self._process_command_help(para_list) 250 elif command.startswith(ToolCommandType.TOOLCMD_KEY_SHOW): 251 self._process_command_show(para_list, productform) 252 elif command.startswith(ToolCommandType.TOOLCMD_KEY_GEN): 253 self._process_command_gen(command, options) 254 elif command.startswith(ToolCommandType.TOOLCMD_KEY_RUN): 255 self._process_command_run(command, options) 256 elif command.startswith(ToolCommandType.TOOLCMD_KEY_QUIT): 257 self._process_command_quit(command) 258 elif command.startswith(ToolCommandType.TOOLCMD_KEY_LIST): 259 self._process_command_device(command) 260 else: 261 print("The %s command is not supported." % command) 262 except (AttributeError, IOError, IndexError, ImportError, NameError, 263 RuntimeError, SystemError, TypeError, ValueError, 264 UnicodeError) as exception: 265 LOG.exception(exception, exc_info=False) 266 267 @classmethod 268 def _process_command_help(cls, para_list): 269 if para_list[0] == ToolCommandType.TOOLCMD_KEY_HELP: 270 display_help_info(para_list) 271 else: 272 LOG.error("Wrong help command.") 273 return 274 275 @classmethod 276 def _process_command_show(cls, para_list, productform="phone"): 277 if para_list[0] == ToolCommandType.TOOLCMD_KEY_SHOW: 278 display_show_info(para_list, productform) 279 else: 280 LOG.error("Wrong show command.") 281 return 282 283 @classmethod 284 def _process_command_gen(cls, command, options): 285 if command == ToolCommandType.TOOLCMD_KEY_GEN: 286 Gen().process_command_gen(options) 287 else: 288 LOG.error("Wrong gen command.") 289 return 290 291 @classmethod 292 def _process_command_run(cls, command, options): 293 if command == ToolCommandType.TOOLCMD_KEY_RUN: 294 Run().process_command_run(command, options) 295 else: 296 LOG.error("Wrong run command.") 297 return 298 299 @classmethod 300 def _process_command_device(cls, command): 301 if command == ToolCommandType.TOOLCMD_KEY_LIST: 302 env_manager = EnvironmentManager() 303 env_manager.list_devices() 304 else: 305 LOG.error("Wrong list command.") 306 return 307 308 @classmethod 309 def _process_command_quit(cls, command): 310 if command == ToolCommandType.TOOLCMD_KEY_QUIT: 311 env_manager = EnvironmentManager() 312 env_manager.env_stop() 313 sys.exit(0) 314 else: 315 LOG.error("Wrong exit command.") 316 return 317 318 @classmethod 319 def _build_version(cls, product_form): 320 is_build_version = UserConfigManager().get_user_config_flag( 321 "build", "version") 322 323 project_root_path = sys.source_code_root_path 324 if project_root_path == "": 325 return True 326 327 build_result = True 328 if is_lite_product(product_form, sys.source_code_root_path): 329 if not is_build_version: 330 return True 331 from core.build.build_lite_manager import BuildLiteManager 332 build_lite_manager = BuildLiteManager(project_root_path) 333 build_result = build_lite_manager.build_version(product_form) 334 else: 335 from core.build.build_manager import BuildManager 336 build_manager = BuildManager() 337 if is_build_version: 338 build_result = build_manager.build_version(project_root_path, 339 product_form) 340 else: 341 build_result = build_manager.build_gn_file(project_root_path, 342 product_form) 343 return build_result 344 345 346############################################################################## 347############################################################################## 348