未验证 提交 72128aa4 编写于 作者: O openharmony_ci 提交者: Gitee

!133 合并主干修改

Merge pull request !133 from liguangjie/OpenHarmony-3.1-Release
......@@ -39,6 +39,7 @@ def main():
entry_points={
'driver': [
'drivers=xdevice_extension._core.driver.drivers',
'openharmony=xdevice_extension._core.driver.openharmony',
'kunpeng=xdevice_extension._core.driver.kunpeng'
],
'parser': [
......
......@@ -137,6 +137,7 @@ class DeviceTestType(object):
build_only_test = "BuildOnlyTestLite"
ltp_posix_test = "LtpPosixTest"
oh_kernel_test = "OHKernelTest"
oh_jsunit_test = "OHJSUnitTest"
@dataclass
......@@ -191,6 +192,7 @@ class ListenerType:
upload = "Upload"
collect = "Collect"
collect_lite = "CollectLite"
collect_pass = "CollectPass"
@dataclass
......@@ -210,6 +212,8 @@ class CommonParserType:
junit = "JUnit"
ltp_posix = "LtpPosixTest"
oh_kernel_test = "OHKernel"
oh_jsunit = "OHJSUnit"
oh_jsunit_list = "OHJSUnitList"
@dataclass
......@@ -238,7 +242,7 @@ class CKit:
shell = "ShellKit"
testbundle = "TestBundleKit"
appinstall = "AppInstallKit"
component = "ComponentKit"
@dataclass
class GTestConst(object):
......
......@@ -23,6 +23,7 @@ import shutil
import zipfile
import tempfile
import stat
import re
from dataclasses import dataclass
from xdevice import ParamError
......@@ -1567,6 +1568,7 @@ class JSUnitTestDriver(IDriver):
"""
def __init__(self):
self.xml_output = "false"
self.timeout = 80 * 1000
self.start_time = None
self.result = ""
......@@ -1611,7 +1613,7 @@ class JSUnitTestDriver(IDriver):
self.error_message = exception
if not getattr(exception, "error_no", ""):
setattr(exception, "error_no", "03409")
LOG.exception(self.error_message, exc_info=True, error_no="03409")
LOG.exception(self.error_message, exc_info=False, error_no="03409")
raise exception
finally:
self.config.device.stop_catch_device_log()
......@@ -1620,52 +1622,129 @@ class JSUnitTestDriver(IDriver):
def generate_console_output(self, device_log_file, request, timeout):
LOG.info("prepare to read device log, may wait some time")
result_message = self.read_device_log(device_log_file, timeout)
report_name = request.get_module_name()
message_list = list()
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")
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
for i in range(len(label_list[0])):
if label_list[0][i] == 1: # this is the start label
if i + 1 < len(label_list[0]): # peek backward
if label_list[0][i + 1] == 1: # lack the end label
message_list.insert(label_list[1][i + 1],
"app Log: [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
else: # at the tail
message_list.insert(-1, "app Log: [suite end]\n")
LOG.warning("there is no suite end")
result_message = "".join(message_list)
message_list.clear()
expect_tests_dict = self._parse_suite_info(suite_info)
self._analyse_tests(request, result_message, expect_tests_dict)
def _analyse_tests(self, request, result_message, expect_tests_dict):
listener_copy = request.listeners.copy()
parsers = get_plugin(
Plugin.PARSER, CommonParserType.jsunit)
if parsers:
parsers = parsers[:1]
for listener in request.listeners:
for listener in listener_copy:
listener.device_sn = self.config.device.device_sn
parser_instances = []
for parser in parsers:
parser_instance = parser.__class__()
parser_instance.suites_name = report_name
parser_instance.suite_name = report_name
parser_instance.listeners = request.listeners
parser_instance.suites_name = request.get_module_name()
parser_instance.listeners = listener_copy
parser_instances.append(parser_instance)
handler = ShellHandler(parser_instances)
handler.parsers[0].expect_tests_dict = expect_tests_dict
process_command_ret(result_message, handler)
def read_device_log(self, device_log_file, timeout=60):
@classmethod
def _parse_suite_info(cls, suite_info):
tests_dict = dict()
test_count = 0
if suite_info:
LOG.debug("Suites info: %s" % suite_info)
json_str = "".join(suite_info)
try:
suite_dict_list = json.loads(json_str).get("suites", [])
for suite_dict in suite_dict_list:
for class_name, test_name_dict_list in suite_dict.items():
tests_dict.update({class_name: []})
for test_name_dict in test_name_dict_list:
for test_name in test_name_dict.values():
test = TestDescription(class_name, test_name)
tests_dict.get(class_name).append(test)
except json.decoder.JSONDecodeError as json_error:
LOG.warning("Suites info is invalid: %s" % json_error)
LOG.debug("Collect suite count is %s, test count is %s" %
(len(tests_dict), test_count))
return tests_dict
def read_device_log_timeout(self, device_log_file,
message_list, timeout):
LOG.info("The timeout is {} seconds".format(timeout))
pattern = "^\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}\\.\\d{3}\\s+(\\d+)"
while time.time() - self.start_time <= timeout:
result_message = ""
with open(device_log_file, "r", encoding='utf-8',
errors='ignore') as file_read_pipe:
errors='ignore') as file_read_pipe:
pid = ""
message_list.clear()
label_list = [[], []] # [-1, 1 ..] [line1, line2 ..]
suite_info = []
while True:
try:
line = file_read_pipe.readline()
except (UnicodeDecodeError, UnicodeError) as error:
except UnicodeError as error:
LOG.warning("While read log file: %s" % error)
if not line:
time.sleep(5) # wait for log write to file
break
if line.lower().find("jsapp:") != -1:
result_message += line
if "[end] run suites end" in line:
LOG.info("Find the end mark then analysis result")
return result_message
# if test not finished, wait 5 seconds
else:
LOG.info("did not find the end mark then wait 5 seconds")
time.sleep(5)
if "[suites info]" in line:
_, pos = re.match(".+\\[suites info]", line).span()
suite_info.append(line[pos:].strip())
if "[start] start run suites" in line: # 发现了任务开始标签
pid, is_update = \
self._init_suites_start(line, pattern, pid)
if is_update:
message_list.clear()
label_list[0].clear()
label_list[1].clear()
if not pid or pid not in line:
continue
message_list.append(line)
if "[suite end]" in line:
label_list[0].append(-1)
label_list[1].append(len(message_list) - 1)
if "[suite start]" in line:
label_list[0].append(1)
label_list[1].append(len(message_list) - 1)
if "[end] run suites end" in line:
LOG.info("Find the end mark then analysis result")
LOG.debug("current JSApp pid= %s" % pid)
return label_list, suite_info, True
else:
LOG.error("Hjsunit run timeout {}s reached".format(timeout))
raise RuntimeError("Hjsunit run timeout!")
LOG.debug("current JSApp pid= %s" % pid)
return label_list, suite_info, False
@classmethod
def _init_suites_start(cls, line, pattern, pid):
matcher = re.match(pattern, line.strip())
if matcher and matcher.group(1):
pid = matcher.group(1)
return pid, True
return pid, False
def _run_jsunit(self, config_file, request):
try:
......@@ -1692,6 +1771,10 @@ class JSUnitTestDriver(IDriver):
hilog_open = os.open(hilog, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
0o755)
with os.fdopen(hilog_open, "a") as hilog_file_pipe:
self.config.device.start_catch_device_log(hilog_file_pipe)
# execute test case
command = "shell aa start -d 123 -a %s -b %s" \
% (ability_name, package)
......@@ -1707,9 +1790,6 @@ class JSUnitTestDriver(IDriver):
% (package, result_value))
raise RuntimeError("hjsunit test run error happened!")
with os.fdopen(hilog_open, "a") as hilog_file_pipe:
self.config.device.start_catch_device_log(hilog_file_pipe)
self.start_time = time.time()
timeout_config = get_config_value('test-timeout',
json_config.get_driver(),
......@@ -1752,6 +1832,7 @@ class LTPPosixTestDriver(IDriver):
self.error_message = ""
self.kits = []
self.config = None
self.handler = None
def __check_environment__(self, device_options):
pass
......@@ -1887,26 +1968,15 @@ class OHKernelTestDriver(IDriver):
self.result = "%s.xml" % \
os.path.join(request.config.report_path,
"result", request.get_module_name())
device_log = get_device_log_file(
request.config.report_path,
request.config.device.__get_serial__(),
"device_log")
hilog = get_device_log_file(
request.config.report_path,
request.config.device.__get_serial__(),
"device_hilog")
device_log_open = os.open(device_log, os.O_WRONLY | os.O_CREAT |
os.O_APPEND, FilePermission.mode_755)
hilog_open = os.open(hilog, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
FilePermission.mode_755)
with os.fdopen(device_log_open, "a") as log_file_pipe, \
os.fdopen(hilog_open, "a") as hilog_file_pipe:
self.config.device.start_catch_device_log(log_file_pipe,
hilog_file_pipe)
with os.fdopen(hilog_open, "a") as hilog_file_pipe:
self.config.device.start_catch_device_log(hilog_file_pipe)
self._run_oh_kernel(config_file, request.listeners, request)
log_file_pipe.flush()
hilog_file_pipe.flush()
except Exception as exception:
self.error_message = exception
......@@ -1934,11 +2004,6 @@ class OHKernelTestDriver(IDriver):
do_module_kit_teardown(request)
def _get_driver_config(self, json_config):
LOG.info("_get_driver_config")
d = dict(json_config.get_driver())
for key in d.keys():
LOG.info("%s:%s" % (key, d[key]))
target_test_path = get_config_value('native-test-device-path',
json_config.get_driver(), False)
test_suite_name = get_config_value('test-suite-name',
......
......@@ -93,7 +93,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
......@@ -370,7 +369,7 @@ class Device(IDevice):
self.hilog_file_pipe = None
def get_recover_result(self, retry=RETRY_ATTEMPTS):
command = "getparam ro.product.model"
command = "param get sys.boot_completed"
stdout = self.execute_shell_command(command, timeout=5 * 1000,
output_flag=False, retry=retry,
abort_on_exception=True).strip()
......
......@@ -86,7 +86,7 @@ class DeviceStateMonitor(object):
while int(time.time()*1000) - start_time < wait_time:
try:
result = self.device.get_recover_result(retry=0)
if result == "ohos":
if "1" in result:
return True
except Exception as exception:
self.device.log.error("wait for boot complete exception: %s"
......
......@@ -817,7 +817,6 @@ class HdcHelper:
device.log.info("%s execute command: hdc target boot" %
convert_serial(device.device_sn))
with HdcHelper.socket(host=device.host, port=device.port) as sock:
HdcHelper.set_device(device, sock)
HdcHelper.handle_shake(sock, device.device_sn)
request = HdcHelper.form_hdc_request("reboot")
......@@ -846,8 +845,7 @@ class HdcHelper:
with HdcHelper.socket(host=device.host, port=device.port,
timeout=timeout) as sock:
output_flag = kwargs.get("output_flag", True)
timeout_msg = '' if (timeout/1000) == 300.0 else \
" with timeout %ss" % str(timeout/1000)
timeout_msg = " with timeout %ss" % str(timeout/1000)
end_mark = kwargs.get("end_mark", "")
read_timeout = kwargs.get("read_timeout", None)
if device.usb_type == DeviceConnectorType.hdc:
......
......@@ -21,10 +21,12 @@ from xdevice import LifeCycle
from xdevice import IListener
from xdevice import platform_logger
from xdevice import TestDescription
from xdevice import ResultCode
from xdevice_extension._core.constants import ListenerType
__all__ = ["CollectingTestListener", "CollectingLiteGTestListener"]
__all__ = ["CollectingTestListener", "CollectingLiteGTestListener",
"CollectingPassListener"]
LOG = platform_logger("Listener")
......@@ -96,3 +98,39 @@ class CollectingLiteGTestListener(IListener):
def get_current_run_results(self):
return self.tests
@Plugin(type=Plugin.LISTENER, id=ListenerType.collect_pass)
class CollectingPassListener(IListener):
"""
listener test status information to the console
"""
def __init__(self):
self.tests = []
def __started__(self, lifecycle, test_result):
pass
def __ended__(self, lifecycle, test_result=None, **kwargs):
if lifecycle == LifeCycle.TestCase:
if not test_result.test_class or not test_result.test_name:
return
if test_result.code != ResultCode.PASSED.value:
return
test = TestDescription(test_result.test_class,
test_result.test_name)
if test not in self.tests:
self.tests.append(test)
else:
LOG.warning("Duplicate testcase: %s#%s" % (
test_result.test_class, test_result.test_name))
def __skipped__(self, lifecycle, test_result):
pass
def __failed__(self, lifecycle, test_result):
pass
def get_current_run_results(self):
return self.tests
......@@ -36,6 +36,7 @@ from xdevice import ParamError
from xdevice import get_file_absolute_path
from xdevice import get_config_value
from xdevice import exec_cmd
from xdevice import ConfigConst
from xdevice_extension._core.constants import CKit
from xdevice_extension._core.environment.dmlib import CollectingOutputReceiver
......@@ -47,8 +48,8 @@ from xdevice_extension._core.utils import convert_serial
__all__ = ["STSKit", "PushKit", "PropertyCheckKit", "ShellKit", "WifiKit",
"ConfigKit", "AppInstallKit", "junit_para_parse",
"gtest_para_parse", "reset_junit_para"]
"ConfigKit", "AppInstallKit", "ComponentKit", "junit_para_parse",
"gtest_para_parse", "reset_junit_para", "oh_jsunit_para_parse"]
LOG = platform_logger("Kit")
......@@ -164,12 +165,12 @@ class PushKit(ITestKit):
LOG.debug(
"Push file finished from {} to {}".format(
os.path.join(root, file), dst))
self.pushed_file.append(file)
self.pushed_file.append(os.path.join(dst, file))
else:
device.hdc_command("file send {} {}".format(real_src_path,
dst))
LOG.debug("Push file finished from {} to {}".format(src, dst))
self.pushed_file.append(real_src_path)
self.pushed_file.append(dst)
for command in self.post_push:
run_command(device, command)
return self.pushed_file, dst
......@@ -301,7 +302,9 @@ class ShellKit(ITestKit):
@Plugin(type=Plugin.TEST_KIT, id=CKit.wifi)
class WifiKit(ITestKit):
def __init__(self):
pass
self.certfilename = ""
self.certpassword = ""
self.wifiname = ""
def __check_config__(self, config):
self.certfilename = get_config_value(
......@@ -664,6 +667,89 @@ class AppInstallKit(ITestKit):
return exec_out
@Plugin(type=Plugin.TEST_KIT, id=CKit.component)
class ComponentKit(ITestKit):
def __init__(self):
self._white_list_file = ""
self._white_list = ""
self._cap_file = ""
self.paths = ""
self.cache_subsystem = set()
self.cache_part = set()
def __check_config__(self, config):
self._white_list_file =\
get_config_value('white-list', config, is_list=False)
self._cap_file = get_config_value('cap-file', config, is_list=False)
self.paths = get_config_value('paths', config)
def __setup__(self, device, **kwargs):
if hasattr(device, ConfigConst.support_component):
return
if device.label in ["phone", "watch", "car", "tv", "tablet", "ivi"]:
command = "cat %s" % self._cap_file
result = device.execute_shell_command(command)
part_set = set()
subsystem_set = set()
if "{" in result:
for item in json.loads(result).get("components", []):
part_set.add(item.get("component", ""))
subsystems, parts = self.get_white_list()
part_set.update(parts)
subsystem_set.update(subsystems)
setattr(device, ConfigConst.support_component,
(subsystem_set, part_set))
self.cache_subsystem.update(subsystem_set)
self.cache_part.update(part_set)
def get_cache(self):
return self.cache_subsystem, self.cache_part
def get_white_list(self):
if not self._white_list and self._white_list_file:
self._white_list = self._parse_white_list()
return self._white_list
def _parse_white_list(self):
subsystem = set()
part = set()
white_json_file = os.path.normpath(self._white_list_file)
if not os.path.isabs(white_json_file):
white_json_file = \
get_file_absolute_path(white_json_file, self.paths)
if os.path.isfile(white_json_file):
subsystem_list = list()
flags = os.O_RDONLY
modes = stat.S_IWUSR | stat.S_IRUSR
with os.fdopen(os.open(white_json_file, flags, modes),
"r") as file_content:
json_result = json.load(file_content)
if "subsystems" in json_result.keys():
subsystem_list.extend(json_result["subsystems"])
for subsystem_item_list in subsystem_list:
for key, value in subsystem_item_list.items():
if key == "subsystem":
subsystem.add(value)
elif key == "components":
for component_item in value:
if "component" in component_item.keys():
part.add(
component_item["component"])
return subsystem, part
def __teardown__(self, device):
if hasattr(device, ConfigConst.support_component):
setattr(device, ConfigConst.support_component, None)
self._white_list_file = ""
self._white_list = ""
self._cap_file = ""
self.cache_subsystem.clear()
self.cache_part.clear()
self.cache_device.clear()
def remount(device):
cmd = "shell mount -o rw,remount /" \
if device.usb_type == DeviceConnectorType.hdc else "remount"
......@@ -770,6 +856,7 @@ def junit_para_parse(device, junit_paras, prefix_char="-e"):
return " ".join(ret_str)
def timeout_callback(proc):
try:
LOG.error("Error: execute command timeout.")
......@@ -860,8 +947,14 @@ def get_app_name(hap_app):
zif_file = zipfile.ZipFile(hap_app)
zif_file.extractall(path=temp_dir)
config_json_file = os.path.join(temp_dir, "config.json")
name_list = ["module.json", "config.json"]
for f_name in os.listdir(temp_dir):
if f_name in name_list:
config_json_file = os.path.join(temp_dir, f_name)
break
if not os.path.exists(config_json_file):
LOG.debug("config.json not in %s.hap" % hap_name)
LOG.debug("Neither config.json nor module.json in %s.hap"
% hap_name)
else:
flags = os.O_RDONLY
modes = stat.S_IWUSR | stat.S_IRUSR
......@@ -878,3 +971,32 @@ def get_app_name(hap_app):
"in %s.hap/config.json" % hap_name)
zif_file.close()
return app_name
def oh_jsunit_para_parse(runner, junit_paras):
junit_paras = dict(junit_paras)
test_type_list = ["function", "performance", "reliability", "security"]
size_list = ["small", "medium", "large"]
level_list = ["0", "1", "2", "3"]
for para_name in junit_paras.keys():
para_name = para_name.strip()
para_values = junit_paras.get(para_name, [])
if para_name == "class":
runner.add_arg(para_name, ",".join(para_values))
elif para_name == "notClass":
runner.add_arg(para_name, ",".join(para_values))
elif para_name == "testType":
if para_values[0] not in test_type_list:
continue
# function/performance/reliability/security
runner.add_arg(para_name, para_values[0])
elif para_name == "size":
if para_values[0] not in size_list:
continue
# size small/medium/large
runner.add_arg(para_name, para_values[0])
elif para_name == "level":
if para_values[0] not in level_list:
continue
# 0/1/2/3/4
runner.add_arg(para_name, para_values[0])
......@@ -297,6 +297,16 @@ class Console(object):
dest=ConfigConst.repeat,
help="number of times that a task is executed"
" repeatedly")
parser.add_argument("-s", "--subsystem",
dest="subsystems",
action="store",
type=str,
help="- Specify the list of subsystem")
parser.add_argument("-p", "--part",
dest="parts",
action="store",
type=str,
help="- Specify the list of part")
self._params_pre_processing(para_list)
(options, unparsed) = parser.parse_known_args(para_list)
if unparsed:
......@@ -336,14 +346,20 @@ class Console(object):
ConfigConst.pass_through: options.testargs})
if not options.resource_path:
resource_path = UserConfigManager(
config_file=options.config, env=options.test_environment).\
config_file=options.config, env=options.test_environment). \
get_resource_path()
setattr(options, ConfigConst.resource_path, resource_path)
if not options.testcases_path:
testcases_path = UserConfigManager(
config_file=options.config, env=options.test_environment).\
config_file=options.config, env=options.test_environment). \
get_testcases_dir()
setattr(options, ConfigConst.testcases_path, testcases_path)
if options.subsystems:
subsystem_list = str(options.subsystems).split(";")
setattr(options, ConfigConst.subsystems, subsystem_list)
if options.parts:
part_list = str(options.parts).split(";")
setattr(options, ConfigConst.parts, part_list)
def command_parser(self, args):
try:
......@@ -420,7 +436,7 @@ class Console(object):
split_list = list(history_command.split())
if "--repeat" in split_list:
pos = split_list.index("--repeat")
split_list = split_list[:pos] + split_list[pos+2:]
split_list = split_list[:pos] + split_list[pos + 2:]
history_command = " ".join(split_list)
(options, _, _, _) = self.argument_parser(history_command.split())
......@@ -747,7 +763,7 @@ TEST_ENVIRONMENT [TEST_ENVIRONMENT ...]
Examples:
run -l <module name>;<module name>
run -tf test/resource/<test file name>.txt
run –l <module name> -sn <device serial number>;<device serial number>
run –l <module name> -respath <path of resource>
run –l <module name> -ta size:large
......@@ -758,22 +774,22 @@ Examples:
run –l <module name> –t ALL
run –l <module name> –td CppTest
run –l <module name> -tcpath resource/testcases
run ssts
run ssts –tc <python script name>;<python script name>
run ssts -sn <device serial number>;<device serial number>
run ssts -respath <path of resource>
... ...
run acts
run acts –tc <python script name>;<python script name>
run acts -sn <device serial number>;<device serial number>
run acts -respath <path of resource>
... ...
run hits
... ...
run --retry
run --retry --session <report folder name>
run --retry --dryrun
......@@ -785,7 +801,7 @@ usage:
list
list history
list <id>
Introduction:
list: display device list
list history: display history record of a serial of tasks
......@@ -797,10 +813,9 @@ Examples:
list 6e****90
"""
GUIDE_INFORMATION = """help:
use help to get information.
usage:
run: Display a list of supported run command.
list: Display a list of supported device and task record.
......
......@@ -231,6 +231,7 @@ class CKit:
liteshell = "LiteShellKit"
app_install = "AppInstallKit"
deploytool = "DeployToolKit"
component = "ComponentKit"
@dataclass
......@@ -253,6 +254,7 @@ class ConfigConst(object):
testlist = "testlist"
testfile = "testfile"
testcase = "testcase"
testdict = "testdict"
device_sn = "device_sn"
report_path = "report_path"
resource_path = "resource_path"
......@@ -270,6 +272,8 @@ class ConfigConst(object):
check_device = "check_device"
configfile = "config"
repeat = "repeat"
subsystems = "subsystems"
parts = "parts"
# Runtime Constant
history_report_path = "history_report_path"
......@@ -281,10 +285,12 @@ class ConfigConst(object):
module_kits = "module_kits"
spt = "spt"
version = "version"
component_mapper = "_component_mapper"
component_base_kit = "component_base_kit"
support_component = "support_component"
class FilePermission(object):
mode_777 = 0o777
mode_755 = 0o755
mode_644 = 0o644
\ No newline at end of file
......@@ -324,7 +324,7 @@ class CppTestParserLite(IParser):
if not error_msg:
error_msg = "Unknown error"
if not check_pub_key_exist():
LOG.debug("error_msg:%s" % error_msg)
LOG.debug("Error msg:%s" % error_msg)
def mark_test_as_failed(self, test):
if not self.state_machine.current_suite and not test.class_name:
......@@ -419,7 +419,7 @@ class CppTestListParserLite(IParser):
def _process_method_line(self, line):
if not self.last_test_class_name:
LOG.error(
"parsed new test case name %s but no test class"
"Parsed new test case name %s but no test class"
" name has been set" % line, error_no="00405")
else:
test = TestDescription(self.last_test_class_name,
......@@ -443,7 +443,7 @@ class CppTestListParserLite(IParser):
self._process_method_line(line)
else:
if not check_pub_key_exist():
LOG.debug("line ignored: %s" % line)
LOG.debug("Line ignored: %s" % line)
def handle_test_tag(self, test_class, test_name):
test_result = self.state_machine.test(reset=True)
......@@ -534,6 +534,7 @@ class CTestParser(IParser):
self.listeners = []
self.product_info = {}
self.is_params = False
self.result_lines = []
def get_suite_name(self):
return self.suites_name
......@@ -600,6 +601,18 @@ class CTestParser(IParser):
if self.state_machine.suites_is_started() or \
self._is_ctest_start_test_run(line):
try:
test_matcher = re.match(r".*(\d+ Tests).+", line)
other_matcher = \
re.match(r".*(\d+ Failures \d+ Ignored).*",line)
if (test_matcher or other_matcher) and \
not self._is_ctest_run(line):
if test_matcher:
self.result_lines.append(test_matcher.group(1))
if other_matcher:
self.result_lines.append(other_matcher.group(1))
line = " ".join(self.result_lines)
self.result_lines.clear()
if self._is_ctest_start_test_run(line):
self.handle_suites_started_tag()
elif self._is_ctest_end_test_run(line):
......
......@@ -24,6 +24,7 @@ from _core.logger import change_logger_level
from _core.plugin import Plugin
from _core.plugin import get_plugin
from _core.utils import convert_serial
from _core.constants import ConfigConst
__all__ = ["EnvironmentManager", "DeviceSelectionOption",
"DeviceAllocationState", "Environment"]
......@@ -200,6 +201,7 @@ class DeviceSelectionOption(object):
self.test_driver = test_source.test_type
self.source_file = ""
self.extend_value = {}
self.required_component = ""
def get_label(self):
return self.label
......@@ -224,6 +226,14 @@ class DeviceSelectionOption(object):
if self.label and self.label != device.label:
return False
if self.required_component and \
hasattr(device, ConfigConst.support_component):
subsystems, parts = getattr(device, ConfigConst.support_component)
required_subsystems, require_part = self.required_component
if required_subsystems not in subsystems and \
require_part not in parts:
return False
return True
......
......@@ -154,17 +154,20 @@ class Task:
plugin_id = None
source = test_descriptor.source
ignore_test = ""
if isinstance(source, TestSource):
if source.test_type is not None:
plugin_id = source.test_type
else:
ignore_test = source.module_name
LOG.error("'%s' no test driver specified" % source.test_name,
error_no="00106")
drivers = get_plugin(plugin_type=Plugin.DRIVER, plugin_id=plugin_id)
if plugin_id is not None:
if len(drivers) == 0:
ignore_test = source.module_name
error_message = "'%s' can not find test driver '%s'" % (
source.test_name, plugin_id)
LOG.error(error_message, error_no="00106")
......@@ -187,6 +190,8 @@ class Task:
if check_result is False:
LOG.error("'%s' can not find suitable test driver '%s'" %
(source.test_name, plugin_id), error_no="00106")
if ignore_test and hasattr(self.config, ConfigConst.component_mapper):
getattr(self.config, ConfigConst.component_mapper).pop(ignore_test)
for desc in test_descriptor.children:
self._init_driver(desc)
......
......@@ -153,7 +153,7 @@ class Scheduler(object):
finally:
Scheduler._clear_test_dict_source()
if getattr(task.config, ConfigConst.test_environment, "") or\
if getattr(task.config, ConfigConst.test_environment, "") or \
getattr(task.config, ConfigConst.configfile, ""):
self._restore_environment()
......@@ -330,6 +330,13 @@ class Scheduler(object):
device_option.source_file = test_source.source_file or \
test_source.source_string
device_options.append(device_option)
if ConfigConst.component_mapper in options.keys():
required_component = options.get(ConfigConst.component_mapper). \
get(test_source.module_name, None)
for device_option in device_options:
device_option.required_component = required_component
return device_options
@staticmethod
......@@ -454,6 +461,11 @@ class Scheduler(object):
LOG.info("")
test_drivers.pop(0)
continue
if getattr(task.config, ConfigConst.component_mapper, ""):
module_name = test_driver[1].source.module_name
self.component_task_setup(task, module_name)
# get environment
try:
environment = self.__allocate_environment__(
......@@ -548,7 +560,7 @@ class Scheduler(object):
LOG.info("copy %s to %s" % (
history_execute_result, target_execute_result))
else:
error_msg = "copy failed! %s not exists!" %\
error_msg = "copy failed! %s not exists!" % \
history_execute_result
raise ParamError(error_msg)
......@@ -622,7 +634,7 @@ class Scheduler(object):
for device in used_devices.values():
if getattr(device, ConfigConst.need_kit_setup, True):
continue
for kit in getattr(device, ConfigConst.task_kits, []):
try:
kit.__teardown__(device)
......@@ -751,9 +763,29 @@ class Scheduler(object):
@staticmethod
def _find_test_root_descriptor(config):
if getattr(config, ConfigConst.task, None) or \
getattr(config, ConfigConst.testargs, None):
Scheduler._pre_component_test(config)
if getattr(config, ConfigConst.subsystems, "") or \
getattr(config, ConfigConst.parts, "") \
or getattr(config, ConfigConst.component_base_kit, ""):
uid = unique_id("Scheduler", "component")
if config.subsystems or config.parts:
test_set = (config.subsystems, config.parts)
else:
kit = getattr(config, ConfigConst.component_base_kit)
test_set = kit.get_white_list()
root = Descriptor(uuid=uid, name="component",
source=TestSetSource(test_set),
container=True)
root.children = find_test_descriptors(config)
return root
# read test list from testdict
if getattr(config, "testdict", "") != "" and getattr(
config, "testfile", "") == "":
if getattr(config, ConfigConst.testdict, "") != "" and getattr(
config, ConfigConst.testfile, "") == "":
uid = unique_id("Scheduler", "testdict")
root = Descriptor(uuid=uid, name="testdict",
source=TestSetSource(config.testdict),
......@@ -762,9 +794,10 @@ class Scheduler(object):
return root
# read test list from testfile, testlist or task
test_set = getattr(config, "testfile", "") or getattr(
config, "testlist", "") or getattr(config, "task", "") or getattr(
config, "testcase")
test_set = getattr(config, ConfigConst.testfile, "") or getattr(
config, ConfigConst.testlist, "") or getattr(
config, ConfigConst.task, "") or getattr(
config, ConfigConst.testcase)
if test_set:
fname, _ = get_filename_extension(test_set)
uid = unique_id("Scheduler", fname)
......@@ -795,7 +828,7 @@ class Scheduler(object):
case_id, result, error, start_time, end_time, report_path))
if Scheduler.proxy:
Scheduler.proxy.upload_result(case_id, result, error,
start_time, end_time, report_path)
start_time, end_time, report_path)
return
from agent.factory import upload_result
upload_result(case_id, result, error, start_time, end_time,
......@@ -833,9 +866,9 @@ class Scheduler(object):
upload_suite.append(case)
if Scheduler.proxy:
Scheduler.proxy.upload_result(case_id, result, error,
start_time, end_time, report_path)
start_time, end_time, report_path)
return
from agent.factory import upload_batch
from agent.factory import upload_batch
upload_batch(upload_suite)
@classmethod
......@@ -1104,3 +1137,53 @@ class Scheduler(object):
def _clear_test_dict_source(cls):
TestDictSource.exe_type.clear()
TestDictSource.test_type.clear()
@classmethod
def _pre_component_test(cls, config):
if not config.kits:
return
cur_kit = None
for kit in config.kits:
if kit.__class__.__name__ == CKit.component:
cur_kit = kit
break
if not cur_kit:
return
get_white_list = getattr(cur_kit, "get_white_list", None)
if not callable(get_white_list):
return
subsystems, parts = get_white_list()
if not subsystems and not parts:
return
setattr(config, ConfigConst.component_base_kit, cur_kit)
@classmethod
def component_task_setup(cls, task, module_name):
component_kit = task.config.get(ConfigConst.component_base_kit, None)
if not component_kit:
# only -p -s .you do not care about the components that can be
# supported. you only want to run the use cases of the current
# component
return
LOG.debug("Start component task setup")
_component_mapper = task.config.get(ConfigConst.component_mapper)
_subsystem, _part = _component_mapper.get(module_name)
is_hit = False
# find in cache. if not find, update cache
cache_subsystem, cache_part = component_kit.get_cache()
if _subsystem in cache_subsystem or _part in cache_subsystem:
is_hit = True
if not is_hit:
env_manager = EnvironmentManager()
for _, manager in env_manager.managers.items():
if getattr(manager, "devices_list", []):
for device in manager.devices_list:
component_kit.__setup__(device)
cache_subsystem, cache_part = component_kit.get_cache()
if _subsystem in cache_subsystem or _part in cache_subsystem:
is_hit = True
if not is_hit:
LOG.warning("%s are skipped, no suitable component found. "
"Require subsystem=%s part=%s, no device match this"
% (module_name, _subsystem, _part))
......@@ -19,11 +19,13 @@
import os
import json
import copy
import stat
from collections import namedtuple
from _core.constants import DeviceTestType
from _core.constants import ModeType
from _core.constants import HostDrivenTestType
from _core.constants import ConfigConst
from _core.exception import ParamError
from _core.logger import platform_logger
from _core.utils import get_filename_extension
......@@ -51,6 +53,7 @@ EXT_TYPE_DICT = {".hap": DeviceTestType.hap_test,
PY_SUFFIX = ".py"
PYD_SUFFIX = ".pyd"
MODULE_CONFIG_SUFFIX = ".json"
MODULE_INFO_SUFFIX = ".moduleInfo"
MAX_DIR_DEPTH = 6
LOG = platform_logger("TestSource")
......@@ -79,14 +82,14 @@ def _get_testcases_dirs(config):
from xdevice import Variables
# add config.testcases_path and its subfolders
testcases_dirs = []
if getattr(config, "testcases_path", ""):
if getattr(config, ConfigConst.testcases_path, ""):
testcases_dirs = [config.testcases_path]
_append_subfolders(config.testcases_path, testcases_dirs)
# add inner testcases dir and its subfolders
inner_testcases_dir = os.path.abspath(os.path.join(
Variables.top_dir, "testcases"))
if getattr(config, "testcases_path", "") and os.path.normcase(
if getattr(config, ConfigConst.testcases_path, "") and os.path.normcase(
config.testcases_path) != os.path.normcase(inner_testcases_dir):
testcases_dirs.append(inner_testcases_dir)
_append_subfolders(inner_testcases_dir, testcases_dirs)
......@@ -109,7 +112,7 @@ def _append_subfolders(testcases_path, testcases_dirs):
def find_testdict_descriptors(config):
from xdevice import Variables
if getattr(config, "testdict", "") == "":
if getattr(config, ConfigConst.testdict, "") == "":
return None
testdict = config.testdict
test_descriptors = []
......@@ -128,27 +131,56 @@ def find_testdict_descriptors(config):
return test_descriptors
def _append_component_test_source(config, testcases_dir, test_sources):
subsystem_list = config.subsystems if config.subsystems else list()
part_list = config.parts if config.parts else list()
module_info_files = _get_component_info_file(testcases_dir)
result_dict = dict()
for info_file in module_info_files:
flags = os.O_RDONLY
modes = stat.S_IWUSR | stat.S_IRUSR
with os.fdopen(os.open(info_file, flags, modes), "r") as f_handler:
result_dict.update(json.load(f_handler))
module_name = result_dict.get("module_name", "")
part_name = result_dict.get("part_name", "")
subsystem_name = result_dict.get("subsystem", "")
if not module_name or not part_name or not subsystem_name:
continue
module_config_file = \
os.path.join(os.path.dirname(info_file), module_name)
is_append = True
if subsystem_list or part_list:
if part_name not in part_list and \
subsystem_name not in subsystem_list:
is_append = False
if is_append:
getattr(config, ConfigConst.component_mapper, dict()).update(
{module_name: (subsystem_name, part_name)})
test_sources.append(module_config_file)
def _get_test_sources(config, testcases_dirs):
test_sources = []
# get test sources from testcases_dirs
if not config.testfile and not config.testlist and not config.testcase \
and config.task:
and not config.subsystems and not config.parts and not \
getattr(config, ConfigConst.component_base_kit, "") and\
config.task:
for testcases_dir in testcases_dirs:
_append_module_test_source(testcases_dir, test_sources)
return test_sources
# get test sources from config.testlist
if getattr(config, "testlist", ""):
if getattr(config, ConfigConst.testlist, ""):
for test_source in config.testlist.split(";"):
if test_source.strip():
test_sources.append(test_source.strip())
return test_sources
# get test sources from config.testfile
if getattr(config, "testfile", ""):
if getattr(config, ConfigConst.testfile, ""):
test_file = _get_test_file(config, testcases_dirs)
import stat
flags = os.O_RDONLY
modes = stat.S_IWUSR | stat.S_IRUSR
with os.fdopen(os.open(test_file, flags, modes), "r") as file_content:
......@@ -157,11 +189,20 @@ def _get_test_sources(config, testcases_dirs):
test_sources.append(line.strip())
# get test sources from config.testcase
if getattr(config, "testcase", ""):
if getattr(config, ConfigConst.testcase, ""):
for test_source in config.testcase.split(";"):
if test_source.strip():
test_sources.append(test_source.strip())
return test_sources
# get test sources according *.moduleInfo file
if getattr(config, ConfigConst.subsystems, []) or getattr(
config, ConfigConst.parts, []) or \
getattr(config, ConfigConst.component_base_kit, ""):
setattr(config, ConfigConst.component_mapper, dict())
for testcases_dir in testcases_dirs:
_append_component_test_source(config, testcases_dir, test_sources)
return test_sources
return test_sources
......@@ -370,6 +411,18 @@ def _get_testcase_config_file(filename):
return None
def _get_component_info_file(entry_dir):
module_files = []
if not os.path.isdir(entry_dir):
return module_files
for item in os.listdir(entry_dir):
item_path = os.path.join(entry_dir, item)
if os.path.isfile(item_path) and item_path.endswith(
MODULE_INFO_SUFFIX):
module_files.append(item_path)
return module_files
def _get_test_type(config_file, test_driver, ext):
if test_driver:
return test_driver
......
......@@ -487,8 +487,10 @@ class ResultReporter(IReporter):
allowZip64=True)
try:
LOG.info("executing compress process, please wait...")
long_size_file = []
for src_path, target_path in file_path_list:
zip_object.write(src_path, target_path)
long_size_file.append((src_path, target_path))
self._write_long_size_file(zip_object, long_size_file)
LOG.info("generate zip file: %s", zipped_file)
except zipfile.BadZipFile as bad_error:
LOG.error("zip report folder error: %s" % bad_error.args)
......@@ -644,3 +646,16 @@ class ResultReporter(IReporter):
def get_path_of_summary_report(cls):
if cls.summary_report_result:
return cls.summary_report_result[0][0]
@classmethod
def _write_long_size_file(cls, zip_object, long_size_file):
for filename, arcname in long_size_file:
zip_info = zipfile.ZipInfo.from_file(filename, arcname)
zip_info.compress_type = getattr(zip_object, "compression",
zipfile.ZIP_DEFLATED)
if hasattr(zip_info, "_compresslevel"):
_compress_level = getattr(zip_object, "compresslevel", None)
setattr(zip_info, "_compresslevel", _compress_level)
with open(filename, "rb") as src, \
zip_object.open(zip_info, "w") as des:
shutil.copyfileobj(src, des, 1024 * 1024 * 8)
......@@ -351,7 +351,7 @@ class MountKit(ITestKit):
try:
os.remove(os.path.join(remote_info.get("dir"),
os.path.basename(_file)))
except Exception as _:
except OSError as _:
pass
shutil.copy(_file, remote_info.get("dir"))
if check_server_file(_file, remote_info.get("dir")):
......@@ -552,6 +552,8 @@ class RootFsKit(ITestKit):
class QueryKit(ITestKit):
def __init__(self):
self.mount_kit = MountKit()
self.query = ""
self.properties = ""
def __check_config__(self, config):
setattr(self.mount_kit, "mount_list",
......
......@@ -246,6 +246,10 @@ def get_file_absolute_path(input_name, paths=None, alt_dir=None):
_inputs.append(input_name.replace("resource/", "", 1))
elif input_name.startswith("testcases/"):
_inputs.append(input_name.replace("testcases/", "", 1))
elif input_name.startswith("resource\\"):
_inputs.append(input_name.replace("resource\\", "", 1))
elif input_name.startswith("testcases\\"):
_inputs.append(input_name.replace("testcases\\", "", 1))
for _input in _inputs:
for path in abs_paths:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册