mirror of
https://github.com/openharmony/test_xdevice.git
synced 2026-07-19 18:23:38 -04:00
!145 增加日志收集DFX功能,修改任务日志打印格式,增加重跑配置项
Merge pull request !145 from liguangjie/master
This commit is contained in:
@@ -24,6 +24,7 @@ import shutil
|
||||
import zipfile
|
||||
import tempfile
|
||||
import stat
|
||||
from collections import namedtuple
|
||||
from dataclasses import dataclass
|
||||
|
||||
from xdevice import ParamError
|
||||
@@ -62,6 +63,7 @@ from xdevice import unlock_device
|
||||
from ohos.environment.dmlib import process_command_ret
|
||||
from ohos.environment.dmlib import DisplayOutputReceiver
|
||||
from ohos.testkit.kit import junit_dex_para_parse
|
||||
from ohos.parser.parser import _ACE_LOG_MARKER
|
||||
|
||||
__all__ = ["CppTestDriver", "DexTestDriver", "HapTestDriver",
|
||||
"JSUnitTestDriver", "JUnitTestDriver", "RemoteTestRunner",
|
||||
@@ -1504,7 +1506,7 @@ class RemoteDexRunner:
|
||||
self.config.device.execute_shell_command(
|
||||
command, timeout=self.config.timeout,
|
||||
receiver=handler, retry=0)
|
||||
except ConnectionResetError as _:
|
||||
except ConnectionResetError as _: # pylint:disable=undefined-variable
|
||||
if len(listener) == 1 and isinstance(listener[0],
|
||||
CollectingTestListener):
|
||||
LOG.info("Try subprocess ")
|
||||
@@ -2224,7 +2226,7 @@ class JSUnitTestDriver(IDriver):
|
||||
label_list, suite_info, is_suites_end = self.read_device_log_timeout(
|
||||
device_log_file, message_list, timeout)
|
||||
if not is_suites_end:
|
||||
message_list.append("app Log: [end] run suites end\n")
|
||||
message_list.append(_ACE_LOG_MARKER + ": [end] run suites end\n")
|
||||
LOG.warning("there is no suites end")
|
||||
if len(label_list[0]) > 0 and sum(label_list[0]) != 0:
|
||||
# the problem happened! when the sum of label list is not zero
|
||||
@@ -2242,13 +2244,13 @@ class JSUnitTestDriver(IDriver):
|
||||
continue
|
||||
# check the start label, then peek next position
|
||||
if i + 1 == len(label_list[0]): # next position at the tail
|
||||
message_list.insert(-1, "app Log: [suite end]\n")
|
||||
message_list.insert(-1, _ACE_LOG_MARKER + ": [suite end]\n")
|
||||
LOG.warning("there is no suite end")
|
||||
continue
|
||||
if label_list[0][i + 1] != 1: # 0 present the end label
|
||||
continue
|
||||
message_list.insert(label_list[1][i + 1],
|
||||
"app Log: [suite end]\n")
|
||||
_ACE_LOG_MARKER + ": [suite end]\n")
|
||||
LOG.warning("there is no suite end")
|
||||
for j in range(i + 1, len(label_list[1])):
|
||||
label_list[1][j] += 1 # move the index to next
|
||||
@@ -2338,7 +2340,7 @@ class JSUnitTestDriver(IDriver):
|
||||
if not line:
|
||||
time.sleep(5) # wait for log write to file
|
||||
break
|
||||
if line.lower().find("jsapp:") != -1:
|
||||
if line.lower().find(_ACE_LOG_MARKER + ":") != -1:
|
||||
if "[suites info]" in line:
|
||||
_, pos = re.match(".+\\[suites info]", line).span()
|
||||
suite_info.append(line[pos:].strip())
|
||||
@@ -2389,8 +2391,7 @@ class JSUnitTestDriver(IDriver):
|
||||
self.config.resource_path,
|
||||
self.config.testcases_path)
|
||||
|
||||
package, ability_name, runner, testcase_timeout = \
|
||||
self._get_driver_config(json_config)
|
||||
driver_config = self._get_driver_config(json_config)
|
||||
# bms not check release type
|
||||
self.config.device.execute_shell_command("bm set -d enable")
|
||||
# turn auto rotation off
|
||||
@@ -2401,7 +2402,8 @@ class JSUnitTestDriver(IDriver):
|
||||
# execute test case
|
||||
command = "aa start -p %s -n %s " \
|
||||
"-s unittest %s -s rawLog true -s timeout %s" \
|
||||
% (package, ability_name, runner, testcase_timeout)
|
||||
% (driver_config.package, driver_config.ability_name,
|
||||
driver_config.runner, driver_config.testcase_timeout)
|
||||
result_value = self.config.device.execute_shell_command(
|
||||
command, timeout=self.timeout)
|
||||
if self.xml_output == "true":
|
||||
@@ -2409,7 +2411,7 @@ class JSUnitTestDriver(IDriver):
|
||||
if report_name:
|
||||
self.config.target_test_path = "/%s/%s/%s/%s/%s/" \
|
||||
% ("sdcard", "Android",
|
||||
"data", package, "cache")
|
||||
"data", driver_config.package, "cache")
|
||||
result = ResultManager(report_name,
|
||||
self.config.report_path,
|
||||
self.config.device,
|
||||
@@ -2445,7 +2447,8 @@ class JSUnitTestDriver(IDriver):
|
||||
if not package:
|
||||
raise ParamError("Can't find package in config file.",
|
||||
error_no="03201")
|
||||
return package, ability_name, runner, testcase_timeout
|
||||
DriverConfig = namedtuple('DriverConfig', 'package ability_name runner testcase_timeout')
|
||||
return DriverConfig(package, ability_name, runner, testcase_timeout)
|
||||
|
||||
def run_js_outer(self, request):
|
||||
try:
|
||||
@@ -2473,6 +2476,7 @@ class JSUnitTestDriver(IDriver):
|
||||
timeout=30 * 1000)
|
||||
time.sleep(10)
|
||||
|
||||
self.config.device.set_device_report_path(request.config.report_path)
|
||||
self.config.device.connector_command("shell hilog -r", timeout=30 * 1000)
|
||||
self._run_jsunit_outer(config_file, request)
|
||||
except Exception as exception:
|
||||
@@ -2482,6 +2486,10 @@ class JSUnitTestDriver(IDriver):
|
||||
LOG.exception(self.error_message, exc_info=False, error_no="03409")
|
||||
raise exception
|
||||
finally:
|
||||
serial = "{}_{}".format(str(self.config.device.__get_serial__()), time.time_ns())
|
||||
log_tar_file_name = "{}_{}".format(str(serial).replace(
|
||||
":", "_"), request.get_module_name())
|
||||
self.config.device.start_get_crash_log(log_tar_file_name)
|
||||
self.config.device.stop_catch_device_log()
|
||||
self.result = check_result_report(
|
||||
request.config.report_path, self.result, self.error_message)
|
||||
@@ -2513,6 +2521,7 @@ class JSUnitTestDriver(IDriver):
|
||||
0o755)
|
||||
|
||||
with os.fdopen(hilog_open, "a") as hilog_file_pipe:
|
||||
self.config.device.clear_crash_log()
|
||||
self.config.device.start_catch_device_log(
|
||||
hilog_file_pipe=hilog_file_pipe)
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
from xdevice import ParamError
|
||||
from xdevice import IDriver
|
||||
@@ -239,6 +240,8 @@ class OHJSUnitTestDriver(IDriver):
|
||||
"test source '%s' not exists" %
|
||||
request.root.source.source_string, error_no="00110")
|
||||
LOG.debug("Test case file path: %s" % suite_file)
|
||||
self.config.device.set_device_report_path(request.config.report_path)
|
||||
|
||||
hilog = get_device_log_file(request.config.report_path,
|
||||
request.config.device.__get_serial__() + "_" + request.
|
||||
get_module_name(),
|
||||
@@ -248,6 +251,7 @@ class OHJSUnitTestDriver(IDriver):
|
||||
0o755)
|
||||
self.config.device.execute_shell_command(command="hilog -r")
|
||||
with os.fdopen(hilog_open, "a") as hilog_file_pipe:
|
||||
self.config.device.clear_crash_log()
|
||||
self.config.device.start_catch_device_log(hilog_file_pipe=hilog_file_pipe)
|
||||
self._run_oh_jsunit(config_file, request)
|
||||
except Exception as exception:
|
||||
@@ -257,6 +261,10 @@ class OHJSUnitTestDriver(IDriver):
|
||||
LOG.exception(self.error_message, exc_info=True, error_no="03409")
|
||||
raise exception
|
||||
finally:
|
||||
serial = "{}_{}".format(str(self.config.device.__get_serial__()), time.time_ns())
|
||||
log_tar_file_name = "{}_{}".format(str(serial).replace(
|
||||
":", "_"), request.get_module_name())
|
||||
self.config.device.start_get_crash_log(log_tar_file_name)
|
||||
self.config.device.stop_catch_device_log()
|
||||
self.result = check_result_report(
|
||||
request.config.report_path, self.result, self.error_message)
|
||||
@@ -291,7 +299,7 @@ class OHJSUnitTestDriver(IDriver):
|
||||
self.config.device.connector_command("target mount")
|
||||
do_module_kit_setup(request, self.kits)
|
||||
self.runner = OHJSUnitTestRunner(self.config)
|
||||
self.runner.suite_name = request.get_module_name()
|
||||
self.runner.suites_name = request.get_module_name()
|
||||
# execute test case
|
||||
self._get_runner_config(json_config)
|
||||
oh_jsunit_para_parse(self.runner, self.config.testargs)
|
||||
@@ -334,10 +342,12 @@ class OHJSUnitTestDriver(IDriver):
|
||||
json_config.get_driver(), False)
|
||||
bundle = get_config_value('bundle-name',
|
||||
json_config. get_driver(), False)
|
||||
is_rerun = get_config_value('rerun', json_config.get_driver(), False)
|
||||
|
||||
self.config.package_name = package
|
||||
self.config.module_name = module
|
||||
self.config.bundle_name = bundle
|
||||
self.rerun = True if is_rerun == 'true' else False
|
||||
|
||||
if not package and not module:
|
||||
raise ParamError("Neither package nor moodle is found"
|
||||
@@ -364,7 +374,7 @@ class OHJSUnitTestDriver(IDriver):
|
||||
test_to_run = self._collect_test_to_run()
|
||||
LOG.info("Collected test count is: %s" % (len(test_to_run)
|
||||
if test_to_run else 0))
|
||||
if not test_to_run:
|
||||
if not test_to_run or not self.rerun:
|
||||
self.runner.run(listener)
|
||||
else:
|
||||
self._run_with_rerun(listener, test_to_run)
|
||||
@@ -429,7 +439,7 @@ class OHJSUnitTestDriver(IDriver):
|
||||
class OHJSUnitTestRunner:
|
||||
def __init__(self, config):
|
||||
self.arg_list = {}
|
||||
self.suite_name = None
|
||||
self.suites_name = None
|
||||
self.config = config
|
||||
self.rerun_attemp = 3
|
||||
self.suite_recorder = {}
|
||||
@@ -459,7 +469,7 @@ class OHJSUnitTestRunner:
|
||||
parser_instances = []
|
||||
for parser in parsers:
|
||||
parser_instance = parser.__class__()
|
||||
parser_instance.suite_name = self.suite_name
|
||||
parser_instance.suites_name = self.suite_name
|
||||
parser_instance.listeners = listener
|
||||
parser_instances.append(parser_instance)
|
||||
handler = ShellHandler(parser_instances)
|
||||
|
||||
@@ -80,7 +80,7 @@ def perform_device_action(func):
|
||||
except ReportException as error:
|
||||
self.log.exception("Generate report error!", exc_info=False)
|
||||
exception = error
|
||||
except (ConnectionResetError, ConnectionRefusedError) as error:
|
||||
except (ConnectionResetError, ConnectionRefusedError) as error: # pylint:disable=undefined-variable
|
||||
self.log.error("error type: %s, error: %s" %
|
||||
(error.__class__.__name__, error))
|
||||
cmd = "hdc_std target boot"
|
||||
@@ -111,7 +111,6 @@ def perform_device_action(func):
|
||||
self.log.exception("error type: %s, error: %s" % (
|
||||
error.__class__.__name__, error), exc_info=False)
|
||||
exception = error
|
||||
raise exception
|
||||
|
||||
return device_action
|
||||
|
||||
@@ -409,8 +408,9 @@ class Device(IDevice):
|
||||
self.device_hilog_proc = None
|
||||
self.hilog_file_pipe = None
|
||||
|
||||
def start_hilog_task(self):
|
||||
self._clear_crash_log()
|
||||
def start_hilog_task(self, log_size="50M"):
|
||||
self._sync_device_time()
|
||||
self.clear_crash_log()
|
||||
# 先停止一下
|
||||
cmd = "hilog -w stop"
|
||||
out = self.execute_shell_command(cmd)
|
||||
@@ -419,8 +419,8 @@ class Device(IDevice):
|
||||
out = self.execute_shell_command(cmd)
|
||||
cmd = "rm -rf /data/log/hilog/*"
|
||||
out = self.execute_shell_command(cmd)
|
||||
# 开始日志任务 设置落盘文件个数最大值1000,链接https://gitee.com/openharmony/hiviewdfx_hilog
|
||||
cmd = "hilog -w start -n 1000"
|
||||
# 开始日志任务 设置落盘文件个数最大值1000, 单个文件20M,链接https://gitee.com/openharmony/hiviewdfx_hilog
|
||||
cmd = "hilog -w start -l {} -n 1000".format(log_size)
|
||||
out = self.execute_shell_command(cmd)
|
||||
LOG.info("Execute command: {}, result is {}".format(cmd, out))
|
||||
|
||||
@@ -428,14 +428,14 @@ class Device(IDevice):
|
||||
cmd = "hilog -w stop"
|
||||
out = self.execute_shell_command(cmd)
|
||||
# 把hilog文件夹下所有文件拉出来 由于hdc不支持整个文件夹拉出只能采用先压缩再拉取文件
|
||||
cmd = "tar -zcvf /data/log/hilog_{}.tar.gz /data/log/hilog/".format(log_name)
|
||||
cmd = "cd /data/log/hilog && tar -zcvf /data/log/hilog_{}.tar.gz *".format(log_name)
|
||||
out = self.execute_shell_command(cmd)
|
||||
LOG.info("Execute command: {}, result is {}".format(cmd, out))
|
||||
self.pull_file("/data/log/hilog_{}.tar.gz".format(log_name), "{}/log/".format(self._device_log_path))
|
||||
cmd = "rm -rf /data/log/hilog_{}.tar.gz".format(log_name)
|
||||
out = self.execute_shell_command(cmd)
|
||||
# 获取crash日志
|
||||
self._start_get_crash_log(log_name)
|
||||
self.start_get_crash_log(log_name)
|
||||
|
||||
def _get_log(self, log_cmd, *params):
|
||||
def filter_by_name(log_name, args):
|
||||
@@ -477,12 +477,11 @@ class Device(IDevice):
|
||||
self.pull_file(temp_path, crash_path)
|
||||
LOG.debug("Finish pull file: %s" % log_name)
|
||||
|
||||
def _start_get_crash_log(self, task_name):
|
||||
def start_get_crash_log(self, task_name):
|
||||
log_array = list()
|
||||
native_crash_cmd = "ls /data/log/faultlog/temp"
|
||||
js_crash_cmd = '"ls /data/log/faultlog/faultlogger | grep jscrash"'
|
||||
block_crash_cmd = '"ls /data/log/faultlog/"'
|
||||
|
||||
# 获取crash日志文件
|
||||
log_array.extend(self._get_log(native_crash_cmd, "cppcrash"))
|
||||
log_array.extend(self._get_log(js_crash_cmd, "jscrash"))
|
||||
@@ -493,18 +492,15 @@ class Device(IDevice):
|
||||
log_name = log_name.strip()
|
||||
self.get_cur_crash_log(crash_path, log_name)
|
||||
|
||||
def _clear_crash_log(self):
|
||||
self._sync_device_time()
|
||||
clear_block_crash_cmd = "rm -rf /data/log/faultlog/"
|
||||
def clear_crash_log(self):
|
||||
clear_block_crash_cmd = "rm -f /data/log/faultlog/*"
|
||||
clear_native_crash_cmd = "rm -f /data/log/faultlog/temp/*"
|
||||
clear_debug_crash_cmd = "rm -f /data/log/faultlog/debug/*"
|
||||
clear_js_crash_cmd = "rm -f /data/log/faultlog/faultlogger/*"
|
||||
self.execute_shell_command(clear_block_crash_cmd)
|
||||
mkdir_block_crash_cmd = "mkdir /data/log/faultlog/"
|
||||
mkdir_native_crash_cmd = "mkdir /data/log/faultlog/temp"
|
||||
mkdir_debug_crash_cmd = "mkdir /data/log/faultlog/debug"
|
||||
mkdir_js_crash_cmd = "mkdir /data/log/faultlog/faultlogger"
|
||||
self.execute_shell_command(mkdir_block_crash_cmd)
|
||||
self.execute_shell_command(mkdir_native_crash_cmd)
|
||||
self.execute_shell_command(mkdir_js_crash_cmd)
|
||||
self.execute_shell_command(mkdir_debug_crash_cmd)
|
||||
self.execute_shell_command(clear_native_crash_cmd)
|
||||
self.execute_shell_command(clear_debug_crash_cmd)
|
||||
self.execute_shell_command(clear_js_crash_cmd)
|
||||
|
||||
def _sync_device_time(self):
|
||||
# 先同步PC和设备的时间
|
||||
@@ -525,6 +521,14 @@ class Device(IDevice):
|
||||
abort_on_exception=True).strip()
|
||||
if stdout:
|
||||
LOG.debug(stdout)
|
||||
if "fail" in stdout:
|
||||
cmd = ["hdc_std", "list", "targets"]
|
||||
result = exec_cmd(cmd)
|
||||
LOG.debug("exec_cmd list targets: {}, current device_sn: {}".format(result, self.device_sn))
|
||||
if self.device_sn in result:
|
||||
return "1"
|
||||
else:
|
||||
return "0"
|
||||
return stdout
|
||||
|
||||
def set_recover_state(self, state):
|
||||
@@ -607,7 +611,7 @@ class Device(IDevice):
|
||||
try:
|
||||
from devicetest.controllers.openharmony import OpenHarmony
|
||||
OpenHarmony.install_harmony_rpc(self)
|
||||
except (ModuleNotFoundError, ImportError) as error:
|
||||
except (ModuleNotFoundError, ImportError) as error: # pylint:disable=undefined-variable
|
||||
self.log.debug(str(error))
|
||||
self.log.error('please check devicetest extension module is exist.')
|
||||
raise Exception(ErrorMessage.Error_01437.Topic)
|
||||
@@ -632,13 +636,18 @@ class Device(IDevice):
|
||||
self.kill_devicetest_agent()
|
||||
|
||||
def is_harmony_rpc_running(self):
|
||||
cmd = 'ps -A | grep %s' % DEVICETEST_HAP_PACKAGE_NAME
|
||||
if hasattr(self, "oh_type") and getattr(self, "oh_type") == "other":
|
||||
bundle_name = DEVICETEST_HAP_PACKAGE_NAME
|
||||
else:
|
||||
# 由于RK上有字段截断问题,因此做出该适配
|
||||
bundle_name = "com.ohos.device"
|
||||
cmd = 'ps -A | grep %s' % bundle_name
|
||||
rpc_running = self.execute_shell_command(cmd).strip()
|
||||
self.log.debug('is_rpc_running out:{}'.format(rpc_running))
|
||||
cmd = 'ps -A | grep %s' % UITEST_NAME
|
||||
uitest_running = self.execute_shell_command(cmd).strip()
|
||||
self.log.debug('is_uitest_running out:{}'.format(uitest_running))
|
||||
if DEVICETEST_HAP_PACKAGE_NAME in rpc_running and UITEST_NAME in uitest_running:
|
||||
if bundle_name in rpc_running and UITEST_NAME in uitest_running:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -650,19 +659,29 @@ class Device(IDevice):
|
||||
for data in out:
|
||||
if UITEST_NAME in data:
|
||||
data = data.split()
|
||||
cmd = 'kill %s' % data[1]
|
||||
if hasattr(self, "oh_type") and getattr(self, "oh_type") == "other":
|
||||
cmd = 'kill %s' % data[1]
|
||||
else:
|
||||
cmd = 'kill %s' % data[0]
|
||||
self.execute_shell_command(cmd).strip()
|
||||
return
|
||||
|
||||
def kill_devicetest_agent(self):
|
||||
cmd = 'ps -A | grep %s' % DEVICETEST_HAP_PACKAGE_NAME
|
||||
if hasattr(self, "oh_type") and getattr(self, "oh_type") == "other":
|
||||
bundle_name = DEVICETEST_HAP_PACKAGE_NAME
|
||||
index = 1
|
||||
else:
|
||||
# 由于RK上有字段截断问题,因此做出该适配
|
||||
bundle_name = "com.ohos.device"
|
||||
index = 0
|
||||
cmd = 'ps -A | grep %s' % bundle_name
|
||||
out = self.execute_shell_command(cmd).strip()
|
||||
self.log.debug('is_rpc_running out:{}'.format(out))
|
||||
out = out.split("\n")
|
||||
for data in out:
|
||||
if DEVICETEST_HAP_PACKAGE_NAME in data:
|
||||
data = data.split()
|
||||
data = 'kill %s' % data[1]
|
||||
for name in out:
|
||||
if bundle_name in name:
|
||||
name = name.split()
|
||||
cmd = 'kill %s' % name[index]
|
||||
self.execute_shell_command(cmd).strip()
|
||||
self.log.debug('stop devicetest ability success.')
|
||||
return
|
||||
@@ -703,10 +722,10 @@ class Device(IDevice):
|
||||
self._h_port, self.d_port)
|
||||
self.connector_command(cmd)
|
||||
try:
|
||||
self._proxy.init(port=self._h_port, addr=self.host, _ad=self)
|
||||
self._proxy.init(port=self._h_port, addr=self.host, device=self)
|
||||
except Exception as _:
|
||||
time.sleep(3)
|
||||
self._proxy.init(port=self._h_port, addr=self.host, _ad=self)
|
||||
self._proxy.init(port=self._h_port, addr=self.host, device=self)
|
||||
|
||||
if self._uitestdeamon is not None:
|
||||
self._uitestdeamon.init(self)
|
||||
|
||||
@@ -35,7 +35,7 @@ from xdevice import CommonParserType
|
||||
|
||||
__all__ = ["CppTestParser", "CppTestListParser", "JunitParser", "JSUnitParser",
|
||||
"OHKernelTestParser", "OHJSUnitTestParser",
|
||||
"OHJSUnitTestListParser"]
|
||||
"OHJSUnitTestListParser", "_ACE_LOG_MARKER"]
|
||||
|
||||
_INFORMATIONAL_MARKER = "[----------]"
|
||||
_START_TEST_RUN_MARKER = "[==========] Running"
|
||||
@@ -1017,7 +1017,7 @@ class OHJSUnitTestParser(IParser):
|
||||
|
||||
def __init__(self):
|
||||
self.state_machine = StateRecorder()
|
||||
self.suite_name = ""
|
||||
self.suites_name = ""
|
||||
self.listeners = []
|
||||
self.current_key = None
|
||||
self.current_value = None
|
||||
@@ -1026,7 +1026,7 @@ class OHJSUnitTestParser(IParser):
|
||||
self.test_run_finished = False
|
||||
|
||||
def get_suite_name(self):
|
||||
return self.suite_name
|
||||
return self.suites_name
|
||||
|
||||
def get_listeners(self):
|
||||
return self.listeners
|
||||
@@ -1160,7 +1160,7 @@ class OHJSUnitTestParser(IParser):
|
||||
for listener in self.get_listeners():
|
||||
suite = copy.copy(suite_result)
|
||||
listener.__ended__(LifeCycle.TestSuites, suite,
|
||||
suites_name=self.suite_name)
|
||||
suites_name=self.suites_name)
|
||||
self.state_machine.current_suite = None
|
||||
|
||||
def mark_test_as_blocked(self, test):
|
||||
|
||||
@@ -249,14 +249,14 @@ class PushKit(ITestKit):
|
||||
for root, _, files in os.walk(real_src_path):
|
||||
for file in files:
|
||||
device.connector_command(
|
||||
"file send {} {}".format(os.path.join(root, file),
|
||||
"file send \"{}\" \"{}\"".format(os.path.join(root, file),
|
||||
dst))
|
||||
LOG.debug(
|
||||
"Push file finished from {} to {}".format(
|
||||
os.path.join(root, file), dst))
|
||||
self.pushed_file.append(os.path.join(dst, file))
|
||||
else:
|
||||
device.connector_command("file send {} {}".format(real_src_path,
|
||||
device.connector_command("file send \"{}\" \"{}\"".format(real_src_path,
|
||||
dst))
|
||||
LOG.debug("Push file finished from {} to {}".format(src, dst))
|
||||
self.pushed_file.append(dst)
|
||||
@@ -689,7 +689,7 @@ class AppInstallKit(ITestKit):
|
||||
LOG.error("The app file {} does not exist".format(app))
|
||||
continue
|
||||
if hasattr(device, "is_harmony") and device.is_harmony:
|
||||
device.connector_command("install {}".format(app_file))
|
||||
device.connector_command("install \"{}\"".format(app_file))
|
||||
else:
|
||||
self.install_hap(device, app_file)
|
||||
self.installed_app.add(app_file)
|
||||
|
||||
@@ -50,6 +50,7 @@ from _core.constants import ProductForm
|
||||
from _core.constants import TestType
|
||||
from _core.constants import CKit
|
||||
from _core.constants import ConfigConst
|
||||
from _core.constants import ReportConst
|
||||
from _core.constants import ModeType
|
||||
from _core.constants import TestExecType
|
||||
from _core.constants import ListenerType
|
||||
@@ -156,6 +157,7 @@ __all__ = [
|
||||
"TestType",
|
||||
"CKit",
|
||||
"ConfigConst",
|
||||
"ReportConst",
|
||||
"ModeType",
|
||||
"TestExecType",
|
||||
"ListenerType",
|
||||
|
||||
@@ -23,10 +23,12 @@ import signal
|
||||
import sys
|
||||
import threading
|
||||
import copy
|
||||
from collections import namedtuple
|
||||
|
||||
from _core.config.config_manager import UserConfigManager
|
||||
from _core.constants import SchedulerType
|
||||
from _core.constants import ConfigConst
|
||||
from _core.constants import ReportConst
|
||||
from _core.constants import ModeType
|
||||
from _core.constants import ToolCommandType
|
||||
from _core.environment.manager_env import EnvironmentManager
|
||||
@@ -39,6 +41,7 @@ from _core.plugin import Plugin
|
||||
from _core.plugin import get_plugin
|
||||
from _core.utils import SplicingAction
|
||||
from _core.utils import get_instance_name
|
||||
from _core.utils import is_python_satisfied
|
||||
from _core.report.result_reporter import ResultReporter
|
||||
|
||||
__all__ = ["Console"]
|
||||
@@ -47,11 +50,12 @@ LOG = platform_logger("Console")
|
||||
try:
|
||||
if platform.system() != 'Windows':
|
||||
import readline
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
except (ModuleNotFoundError, ImportError): # pylint:disable=undefined-variable
|
||||
LOG.warning("Readline module is not exist.")
|
||||
|
||||
MAX_VISIBLE_LENGTH = 49
|
||||
MAX_RESERVED_LENGTH = 46
|
||||
Argument = namedtuple('Argument', 'options unparsed valid_param parser')
|
||||
|
||||
|
||||
class Console(object):
|
||||
@@ -88,9 +92,7 @@ class Console(object):
|
||||
"""
|
||||
Main xDevice console providing user with the interface to interact
|
||||
"""
|
||||
if sys.version < '3.7':
|
||||
LOG.error("Please use python 3.7 or higher version to "
|
||||
"start project")
|
||||
if not is_python_satisfied():
|
||||
sys.exit(0)
|
||||
|
||||
if args is None or len(args) < 2:
|
||||
@@ -324,7 +326,7 @@ class Console(object):
|
||||
valid_param = False
|
||||
parser.print_help()
|
||||
LOG.warning("Parameter parsing system exit exception.")
|
||||
return options, unparsed, valid_param, parser
|
||||
return Argument(options, unparsed, valid_param, parser)
|
||||
|
||||
@classmethod
|
||||
def _params_pre_processing(cls, para_list):
|
||||
@@ -384,16 +386,15 @@ class Console(object):
|
||||
Scheduler.command_queue.append(args)
|
||||
LOG.info("Input command: {}".format(args))
|
||||
para_list = args.split()
|
||||
(options, _, valid_param, parser) = self.argument_parser(
|
||||
para_list)
|
||||
if options is None or not valid_param:
|
||||
argument = self.argument_parser( para_list)
|
||||
if argument.options is None or not argument.valid_param:
|
||||
LOG.warning("Options is None.")
|
||||
return None
|
||||
if options.action == ToolCommandType.toolcmd_key_run and \
|
||||
options.retry:
|
||||
options = self._get_retry_options(options, parser)
|
||||
if options.dry_run:
|
||||
history_report_path = getattr(options,
|
||||
if argument.options.action == ToolCommandType.toolcmd_key_run and \
|
||||
argument.options.retry:
|
||||
argument.options = self._get_retry_options(argument.options, argument.parser)
|
||||
if argument.options.dry_run:
|
||||
history_report_path = getattr(argument.options,
|
||||
"history_report_path", "")
|
||||
self._list_retry_case(history_report_path)
|
||||
return
|
||||
@@ -402,12 +403,12 @@ class Console(object):
|
||||
SuiteReporter.clear_failed_case_list()
|
||||
SuiteReporter.clear_report_result()
|
||||
|
||||
command = options.action
|
||||
command = argument.options.action
|
||||
if command == "":
|
||||
LOG.info("Command is empty.")
|
||||
return
|
||||
|
||||
self._process_command(command, options, para_list, parser)
|
||||
self._process_command(command, argument.options, para_list, argument.parser)
|
||||
except (ParamError, ValueError, TypeError, SyntaxError,
|
||||
AttributeError) as exception:
|
||||
error_no = getattr(exception, "error_no", "00000")
|
||||
@@ -457,18 +458,18 @@ class Console(object):
|
||||
split_list = split_list[:pos] + split_list[pos+2:]
|
||||
history_command = " ".join(split_list)
|
||||
|
||||
(options, _, _, _) = self.argument_parser(history_command.split())
|
||||
options.dry_run = is_dry_run
|
||||
setattr(options, "history_report_path", history_report_path)
|
||||
argument = self.argument_parser(history_command.split())
|
||||
argument.options.dry_run = is_dry_run
|
||||
setattr(argument.options, "history_report_path", history_report_path)
|
||||
# modify history_command -rp param and -sn param
|
||||
for option_tuple in self._get_to_be_replaced_option(parser):
|
||||
history_command = self._replace_history_option(
|
||||
history_command, (input_options, options), option_tuple)
|
||||
history_command, (input_options, argument.options), option_tuple)
|
||||
|
||||
# add history command to Scheduler.command_queue
|
||||
LOG.info("Retry command: %s", history_command)
|
||||
Scheduler.command_queue[-1] = history_command
|
||||
return options
|
||||
return argument.options
|
||||
|
||||
@classmethod
|
||||
def _process_command_help(cls, parser, para_list):
|
||||
@@ -577,8 +578,9 @@ class Console(object):
|
||||
if not params:
|
||||
raise ParamError("no retry case exists")
|
||||
session_id, command, report_path, failed_list = \
|
||||
params[0], params[1], params[2], \
|
||||
[(module, failed) for module, case_list in params[3].items()
|
||||
params[ReportConst.session_id], params[ReportConst.command], \
|
||||
params[ReportConst.report_path], \
|
||||
[(module, failed) for module, case_list in params[ReportConst.unsuccessful_params].items()
|
||||
for failed in case_list]
|
||||
if Scheduler.mode == ModeType.decc:
|
||||
from xdevice import SuiteReporter
|
||||
@@ -662,7 +664,7 @@ class Console(object):
|
||||
options.session else "'%s' has no command executed" % \
|
||||
options.session
|
||||
raise ParamError(error_msg)
|
||||
history_command, history_report_path = params[1], params[2]
|
||||
history_command, history_report_path = params[ReportConst.command], params[ReportConst.report_path]
|
||||
else:
|
||||
history_command, history_report_path = "", ""
|
||||
for command_tuple in Scheduler.command_queue[:-1]:
|
||||
|
||||
@@ -141,6 +141,7 @@ class HostDrivenTestType(object):
|
||||
"""
|
||||
device_test = "DeviceTest"
|
||||
windows_test = "WindowsTest"
|
||||
app_test = "AppTest"
|
||||
|
||||
|
||||
TEST_DRIVER_SET = {
|
||||
@@ -278,6 +279,15 @@ class ConfigConst(object):
|
||||
device_log = "device_log"
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReportConst(object):
|
||||
session_id = "session_id"
|
||||
command = "command"
|
||||
report_path = "report_path"
|
||||
unsuccessful_params = "unsuccessful_params"
|
||||
data_reports = "data_reports"
|
||||
|
||||
|
||||
class FilePermission(object):
|
||||
mode_777 = 0o777
|
||||
mode_755 = 0o755
|
||||
@@ -287,3 +297,4 @@ class FilePermission(object):
|
||||
@dataclass
|
||||
class DeviceConnectorType:
|
||||
hdc = "usb-hdc"
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from concurrent.futures import wait
|
||||
|
||||
from _core.constants import ModeType
|
||||
from _core.constants import ConfigConst
|
||||
from _core.constants import ReportConst
|
||||
from _core.executor.request import Request
|
||||
from _core.logger import platform_logger
|
||||
from _core.plugin import Config
|
||||
@@ -269,11 +270,11 @@ class DriversThread(threading.Thread):
|
||||
for i in Handler.DAV.case_id_list:
|
||||
failed_list.append(i + "#" + i)
|
||||
else:
|
||||
failed_list = params[3].get(module_name, [])
|
||||
failed_list = params[ReportConst.unsuccessful_params].get(module_name, [])
|
||||
except:
|
||||
failed_list = params[3].get(module_name, [])
|
||||
failed_list = params[ReportConst.unsuccessful_params].get(module_name, [])
|
||||
if not failed_list:
|
||||
failed_list = params[3].get(str(module_name).split(".")[0], [])
|
||||
failed_list = params[ReportConst.unsuccessful_params].get(str(module_name).split(".")[0], [])
|
||||
unpassed_test_params.extend(failed_list)
|
||||
LOG.debug("Get unpassed test params %s", unpassed_test_params)
|
||||
return unpassed_test_params
|
||||
@@ -432,7 +433,7 @@ class DriversThread(threading.Thread):
|
||||
from _core.report.result_reporter import ResultReporter
|
||||
params = ResultReporter.get_task_info_params(history_report_path)
|
||||
if params:
|
||||
report_data_dict = dict(params[4])
|
||||
report_data_dict = dict(params[ReportConst.report_path])
|
||||
if execute_result_name in report_data_dict.keys():
|
||||
return report_data_dict.get(execute_result_name)
|
||||
elif execute_result_name.split(".")[0] in \
|
||||
|
||||
@@ -57,6 +57,7 @@ from _core.constants import DeviceLabelType
|
||||
from _core.constants import SchedulerType
|
||||
from _core.constants import ListenerType
|
||||
from _core.constants import ConfigConst
|
||||
from _core.constants import ReportConst
|
||||
from _core.constants import HostDrivenTestType
|
||||
from _core.executor.concurrent import DriversThread
|
||||
from _core.executor.concurrent import QueueMonitorThread
|
||||
@@ -1149,10 +1150,10 @@ class Scheduler(object):
|
||||
history_report_path = \
|
||||
getattr(task.config, ConfigConst.history_report_path, "")
|
||||
params = ResultReporter.get_task_info_params(history_report_path)
|
||||
if params and params[3]:
|
||||
if dict(params[3]).get(module_name, []):
|
||||
if params and params[ReportConst.unsuccessful_params]:
|
||||
if dict(params[ReportConst.unsuccessful_params]).get(module_name, []):
|
||||
failed_flag = True
|
||||
elif dict(params[3]).get(str(module_name).split(".")[0], []):
|
||||
elif dict(params[ReportConst.unsuccessful_params]).get(str(module_name).split(".")[0], []):
|
||||
failed_flag = True
|
||||
return failed_flag
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
from _core.constants import LogType
|
||||
@@ -325,7 +326,8 @@ def remove_encrypt_file_handler():
|
||||
|
||||
def _init_global_logger(name=None):
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
log_format = "[%(asctime)s] [%(name)s] [%(levelname)s] [%(message)s]"
|
||||
log_format = \
|
||||
"[%(asctime)s] [%(thread)d] [%(name)s] [%(levelname)s] [%(message)s]"
|
||||
handler.setFormatter(logging.Formatter(log_format))
|
||||
log = FrameworkLog(name)
|
||||
log.platform_log.setLevel(logging.INFO)
|
||||
@@ -398,7 +400,7 @@ class EncryptFileHandler(RotatingFileHandler):
|
||||
stream = getattr(self, "stream", self._open())
|
||||
stream.write(msg)
|
||||
self.flush()
|
||||
except RecursionError as _:
|
||||
except RecursionError as _: # pylint:disable=undefined-variable
|
||||
raise
|
||||
|
||||
def _encrypt_valid(self):
|
||||
@@ -423,15 +425,17 @@ class EncryptFileHandler(RotatingFileHandler):
|
||||
msg = record.msg
|
||||
if msg and "%s" in msg:
|
||||
msg = msg % record.args
|
||||
info = "[%s] [%s] [%s] %s%s" \
|
||||
% (create_time, name, level_name, msg, "\n")
|
||||
info = "[%s] [%s] [%s] [%s] %s%s" \
|
||||
% (create_time, threading.currentThread().ident, name,
|
||||
level_name, msg, "\n")
|
||||
|
||||
try:
|
||||
return do_rsa_encrypt(info)
|
||||
except ParamError as error:
|
||||
error_no_str = \
|
||||
"ErrorNo={}".format(getattr(error, "error_no", "00113"))
|
||||
info = "[%s] [%s] [%s] [%s] [%s]\n" % (
|
||||
create_time, name, "ERROR", error, error_no_str)
|
||||
info = "[%s] [%s] [%s] [%s] [%s] [%s]\n" % (
|
||||
create_time, threading.currentThread().ident,
|
||||
name, "ERROR", error, error_no_str)
|
||||
self.encrypt_error = bytes(info, "utf-8")
|
||||
return self.encrypt_error
|
||||
|
||||
@@ -24,14 +24,13 @@ from _core.logger import platform_logger
|
||||
from _core.report.reporter_helper import ExecInfo
|
||||
from _core.report.reporter_helper import ReportConstant
|
||||
from _core.report.result_reporter import ResultReporter
|
||||
from _core.utils import is_python_satisfied
|
||||
|
||||
LOG = platform_logger("ReportMain")
|
||||
|
||||
|
||||
def main_report():
|
||||
if sys.version < '3.7':
|
||||
LOG.error("Please use python 3.7 or higher version to start "
|
||||
"project")
|
||||
if not is_python_satisfied():
|
||||
return
|
||||
|
||||
args = sys.argv
|
||||
|
||||
@@ -130,16 +130,6 @@ class ResultReporter(IReporter):
|
||||
self.set_summary_report_result(
|
||||
self.summary_data_path, DataHelper.to_string(test_suites_element))
|
||||
|
||||
if self._check_mode(ModeType.decc):
|
||||
try:
|
||||
from agent.decc import Handler
|
||||
from xdevice import Scheduler
|
||||
LOG.info("Upload task summary result to decc")
|
||||
Handler.upload_task_summary_results(
|
||||
self.get_result_of_summary_report())
|
||||
except ModuleNotFoundError as error:
|
||||
LOG.error("Module not found %s", error.args)
|
||||
|
||||
def _update_test_suites(self, test_suites_element):
|
||||
# initial attributes for test suites element
|
||||
test_suites_attributes, need_update_attributes = \
|
||||
@@ -630,8 +620,7 @@ class ResultReporter(IReporter):
|
||||
LOG.error("%s error!", ReportConstant.task_info_record)
|
||||
return ()
|
||||
|
||||
return result["session_id"], result["command"], result["report_path"],\
|
||||
result["unsuccessful_params"], result["data_reports"]
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def set_summary_report_result(cls, summary_data_path, result_xml):
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import copy
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import platform
|
||||
import argparse
|
||||
@@ -94,7 +95,7 @@ def stop_standing_subprocess(process):
|
||||
signal_value = signal.SIGINT if sys_type == "Windows" \
|
||||
else signal.SIGTERM
|
||||
os.kill(process.pid, signal_value)
|
||||
except (PermissionError, AttributeError, FileNotFoundError,
|
||||
except (PermissionError, AttributeError, FileNotFoundError, # pylint:disable=undefined-variable
|
||||
SystemError) as error:
|
||||
LOG.error("Stop standing subprocess error '%s'" % error)
|
||||
|
||||
@@ -202,7 +203,7 @@ def exec_cmd(cmd, timeout=5 * 60, error_print=True, join_result=False, redirect=
|
||||
else:
|
||||
return err if err else out
|
||||
|
||||
except (TimeoutError, KeyboardInterrupt, AttributeError, ValueError,
|
||||
except (TimeoutError, KeyboardInterrupt, AttributeError, ValueError, # pylint:disable=undefined-variable
|
||||
EOFError, IOError) as _:
|
||||
sys_type = platform.system()
|
||||
if sys_type == "Linux" or sys_type == "Darwin":
|
||||
@@ -454,6 +455,14 @@ def is_config_str(content):
|
||||
return True if "{" in content and "}" in content else False
|
||||
|
||||
|
||||
def is_python_satisfied():
|
||||
mini_version = (3, 7, 0)
|
||||
if sys.version_info > mini_version:
|
||||
return True
|
||||
LOG.error("Please use python {} or higher version to start project".format(mini_version))
|
||||
return False
|
||||
|
||||
|
||||
def get_version():
|
||||
from xdevice import Variables
|
||||
ver = ''
|
||||
|
||||
@@ -66,8 +66,8 @@ def _init_global_config():
|
||||
# set report variables
|
||||
Variables.report_vars.log_dir = "log"
|
||||
Variables.report_vars.report_dir = "reports"
|
||||
Variables.report_vars.log_format = "[%(asctime)s] [%(name)s] " \
|
||||
"[%(levelname)s] %(message)s"
|
||||
Variables.report_vars.log_format = \
|
||||
"[%(asctime)s] [%(thread)d] [%(name)s] [%(levelname)s] %(message)s"
|
||||
Variables.report_vars.log_level = logging.INFO
|
||||
Variables.report_vars.log_handler = "console, file"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user