From b26d7731ba3d116da270442a69a159b4bc08710e Mon Sep 17 00:00:00 2001 From: deveco_xdevice Date: Tue, 5 Nov 2024 21:33:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A4=84=E7=90=86OHJS=E9=A9=B1=E5=8A=A8rer?= =?UTF-8?q?un=E6=97=B6=EF=BC=8C=E5=87=BA=E7=8E=B0App=20died=E7=9A=84?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: deveco_xdevice --- plugins/ohos/src/ohos/executor/listener.py | 2 ++ plugins/ohos/src/ohos/parser/oh_jsunit_parser.py | 2 +- src/xdevice/_core/executor/abs.py | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/ohos/src/ohos/executor/listener.py b/plugins/ohos/src/ohos/executor/listener.py index 0a40a68..34b5983 100644 --- a/plugins/ohos/src/ohos/executor/listener.py +++ b/plugins/ohos/src/ohos/executor/listener.py @@ -180,6 +180,8 @@ class StackReportListener(UniversalReportListener): if suite_item.index != suite_index: continue self.suites.pop(suite.index) + if result_list and result_list[-1].is_completed is not True: + result_list.pop(-1) result_list.extend(results_of_same_suite) break else: diff --git a/plugins/ohos/src/ohos/parser/oh_jsunit_parser.py b/plugins/ohos/src/ohos/parser/oh_jsunit_parser.py index b559cbb..ba4a636 100644 --- a/plugins/ohos/src/ohos/parser/oh_jsunit_parser.py +++ b/plugins/ohos/src/ohos/parser/oh_jsunit_parser.py @@ -226,6 +226,7 @@ class OHJSUnitTestParser(IParser): return if test_info.run_time == 0 or test_info.run_time < self.test_time: test_info.run_time = self.test_time + test_info.is_completed = True for listener in self.get_listeners(): result = copy.copy(test_info) result.code = test_info.code @@ -234,7 +235,6 @@ class OHJSUnitTestParser(IParser): continue if self.runner.retry_times > 1 and result.code == ResultCode.FAILED.value: listener.tests.pop(test_info.index) - test_info.is_completed = True self.clear_current_test_info() def handle_suite_end(self): diff --git a/src/xdevice/_core/executor/abs.py b/src/xdevice/_core/executor/abs.py index ac45a7e..238f876 100644 --- a/src/xdevice/_core/executor/abs.py +++ b/src/xdevice/_core/executor/abs.py @@ -200,6 +200,7 @@ class ReportEventListener(AbsReportListener, ABC): test.stacktrace = test_result.stacktrace test.code = test_result.code test.report = test_result.report + test.is_completed = test_result.is_completed def _handle_test_suites_end(self, test_result, kwargs): if not kwargs.get("suite_report", False): From 553af1e871ddad5ce823ab56214e9efeabf2c2a2 Mon Sep 17 00:00:00 2001 From: deveco_xdevice Date: Thu, 7 Nov 2024 17:20:02 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=8F=90=E4=BA=A4opensource=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=A9=B1=E5=8A=A8=E3=80=81build=20only=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: deveco_xdevice --- plugins/ohos/setup.py | 2 + .../ohos/drivers/build_only_driver_lite.py | 105 ++++++++++++ .../ohos/drivers/opensource_driver_lite.py | 156 ++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 plugins/ohos/src/ohos/drivers/build_only_driver_lite.py create mode 100644 plugins/ohos/src/ohos/drivers/opensource_driver_lite.py diff --git a/plugins/ohos/setup.py b/plugins/ohos/setup.py index c66cbe6..40883eb 100644 --- a/plugins/ohos/setup.py +++ b/plugins/ohos/setup.py @@ -53,6 +53,8 @@ setup( 'oh_kernel_driver=ohos.drivers.oh_kernel_driver', 'oh_yara_driver=ohos.drivers.oh_yara_driver', 'c_driver_lite=ohos.drivers.c_driver_lite', + 'opensource_driver_lite=ohos.drivers.opensource_driver_lite', + 'build_only_driver_lite=ohos.drivers.build_only_driver_lite' ], 'listener': [ 'listener=ohos.executor.listener', diff --git a/plugins/ohos/src/ohos/drivers/build_only_driver_lite.py b/plugins/ohos/src/ohos/drivers/build_only_driver_lite.py new file mode 100644 index 0000000..c649a21 --- /dev/null +++ b/plugins/ohos/src/ohos/drivers/build_only_driver_lite.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +# +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import stat +from ohos.drivers import * +from ohos.constants import ParserType +from ohos.environment.dmlib_lite import generate_report + +__all__ = ["BuildOnlyTestDriver"] +LOG = platform_logger("BuildOnlyTestDriver") + + +@Plugin(type=Plugin.DRIVER, id=DeviceTestType.build_only_test) +class BuildOnlyTestDriver(IDriver): + """ + BuildOnlyTest is a test that runs a native test package on given + device lite device. + """ + config = None + result = "" + error_message = "" + + def __init__(self): + self.file_name = "" + self.config_file = None + self.testcases_path = None + + def __check_environment__(self, device_options): + pass + + def __check_config__(self, config): + pass + + def __execute__(self, request): + self.config = request.config + self.config.device = request.config.environment.devices[0] + self.file_name = request.root.source.test_name + self.config_file = request.root.source.config_file + self.testcases_path = request.config.testcases_path + file_path = self._get_log_file() + result_list = self._get_result_list(file_path) + if len(result_list) == 0: + LOG.error( + "Error: source don't exist %s." % request.root.source. + source_file, error_no="00101") + return + total_result = '' + for result in result_list: + flags = os.O_RDONLY + modes = stat.S_IWUSR | stat.S_IRUSR + with os.fdopen(os.open(result, flags, modes), "r", + encoding="utf-8") as file_content: + result = file_content.read() + if not result.endswith('\n'): + result = '%s\n' % result + total_result = '{}{}'.format(total_result, result) + parsers = get_plugin(Plugin.PARSER, ParserType.build_only_test) + parser_instances = [] + for parser in parsers: + parser_instance = parser.__class__() + parser_instance.suite_name = self.file_name + parser_instance.listeners = request.listeners + parser_instances.append(parser_instance) + handler = ShellHandler(parser_instances) + generate_report(handler, total_result) + + @classmethod + def _get_result_list(cls, file_path): + result_list = list() + for root_path, dirs_path, file_names in os.walk(file_path): + for file_name in file_names: + if file_name == "logfile": + result_list.append(os.path.join(root_path, file_name)) + return result_list + + def _get_log_file(self): + json_config = JsonParser(self.config_file) + log_path = get_config_value('log_path', json_config.get_driver(), + False) + log_path = str(log_path.replace("/", "", 1)) if log_path.startswith( + "/") else str(log_path) + LOG.debug("The log path is:%s" % log_path) + file_path = get_file_absolute_path(log_path, + paths=[self.testcases_path]) + LOG.debug("The file path is:%s" % file_path) + return file_path + + def __result__(self): + return self.result if os.path.exists(self.result) else "" diff --git a/plugins/ohos/src/ohos/drivers/opensource_driver_lite.py b/plugins/ohos/src/ohos/drivers/opensource_driver_lite.py new file mode 100644 index 0000000..2d9ee5d --- /dev/null +++ b/plugins/ohos/src/ohos/drivers/opensource_driver_lite.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +# +# Copyright (c) 2020-2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os +from xdevice import DeviceLabelType +from ohos.drivers import * +from ohos.constants import ParserType +from ohos.drivers.constants import init_remote_server +from ohos.exception import LiteDeviceExecuteCommandError +from ohos.error import ErrorMessage + + +__all__ = ["OpenSourceTestDriver"] +LOG = platform_logger("OpenSourceTestDriver") + + +@Plugin(type=Plugin.DRIVER, id=DeviceTestType.open_source_test) +class OpenSourceTestDriver(IDriver): + """ + OpenSourceTest is a test that runs a native test package on given + device lite device. + """ + config = None + result = "" + error_message = "" + has_param = False + + def __init__(self): + self.rerun = True + self.file_name = "" + self.handler = None + + def __check_environment__(self, device_options): + if len(device_options) != 1 or \ + device_options[0].label != DeviceLabelType.ipcamera: + self.error_message = "check environment failed" + return False + return True + + def __check_config__(self, config=None): + pass + + def __execute__(self, request): + kits = [] + try: + self.config = request.config + setattr(self.config, "command_result", "") + self.config.device = request.config.environment.devices[0] + init_remote_server(self, request) + config_file = request.root.source.config_file + json_config = JsonParser(config_file) + pre_cmd = get_config_value('pre_cmd', json_config.get_driver(), + False) + execute_dir = get_config_value('execute', json_config.get_driver(), + False) + kits = get_kit_instances(json_config, + request.config.resource_path, + request.config.testcases_path) + for kit in kits: + if not Binder.is_executing(): + raise ExecuteTerminate(ErrorMessage.Common.Code_0301013) + copy_list = kit.__setup__(request.config.device, + request=request) + + self.file_name = request.root.source.test_name + self.set_file_name(request, request.root.source.test_name) + self.config.device.execute_command_with_timeout( + command=pre_cmd, timeout=1) + self.config.device.execute_command_with_timeout( + command="cd {}".format(execute_dir), timeout=1) + device_log_file = get_device_log_file( + request.config.report_path, + request.config.device.__get_serial__(), + repeat=request.config.repeat, + repeat_round=request.get_repeat_round()) + device_log_file_open = \ + os.open(device_log_file, os.O_WRONLY | os.O_CREAT | + os.O_APPEND, FilePermission.mode_755) + with os.fdopen(device_log_file_open, "a") as file_name: + for test_bin in copy_list: + if not test_bin.endswith(".run-test"): + continue + if test_bin.startswith("/"): + command = ".%s" % test_bin + else: + command = "./%s" % test_bin + self._do_test_run(command, request) + file_name.write(self.config.command_result) + file_name.flush() + + except (LiteDeviceExecuteCommandError, Exception) as exception: + LOG.error(exception, error_no=getattr(exception, "error_no", + "00000")) + self.error_message = exception + finally: + LOG.info("-------------finally-----------------") + # umount the dirs already mount + for kit in kits: + kit.__teardown__(request.config.device) + self.config.device.close() + report_name = "report" if request.root.source. \ + test_name.startswith("{") else get_filename_extension( + request.root.source.test_name)[0] + self.result = check_result_report( + request.config.report_path, self.result, self.error_message, + report_name) + + def set_file_name(self, request, bin_file): + self.result = "%s.xml" % os.path.join( + request.config.report_path, "result", bin_file) + + def run(self, command=None, listener=None, timeout=20): + parsers = get_plugin(Plugin.PARSER, + ParserType.open_source_test) + parser_instances = [] + for parser in parsers: + parser_instance = parser.__class__() + parser_instance.suite_name = self.file_name + parser_instance.test_name = command.replace("./", "") + parser_instance.listeners = listener + parser_instances.append(parser_instance) + self.handler = ShellHandler(parser_instances) + for _ in range(3): + result, _, error = self.config.device.execute_command_with_timeout( + command=command, case_type=DeviceTestType.open_source_test, + timeout=timeout, receiver=self.handler) + self.config.command_result = result + if "pass" in result.lower(): + break + return error, result, self.handler + + def _do_test_run(self, command, request): + listeners = request.listeners + for listener in listeners: + listener.device_sn = self.config.device.device_sn + error, _, _ = self.run(command, listeners, timeout=60) + if error: + LOG.error( + "Execute %s failed" % command, error_no="00402") + + def __result__(self): + return self.result if os.path.exists(self.result) else "" From 354136ed7cd69f4e9487ff1a6312df488e4826fe Mon Sep 17 00:00:00 2001 From: deveco_xdevice Date: Thu, 7 Nov 2024 20:59:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?1.=E5=A4=84=E7=90=86=E7=BC=96=E7=A0=81=202.?= =?UTF-8?q?=E5=A4=84=E7=90=86rerun=E7=AC=AC=E4=B8=80=E8=BD=AE=E6=9C=AA?= =?UTF-8?q?=E6=94=B6=E9=9B=86=E5=88=B0=E6=89=80=E6=9C=89=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=A5=97=E4=BF=A1=E6=81=AF=E5=AF=BC=E8=87=B4=E7=9A=84=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: deveco_xdevice --- plugins/ohos/src/ohos/environment/dmlib.py | 2 +- plugins/ohos/src/ohos/executor/listener.py | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/plugins/ohos/src/ohos/environment/dmlib.py b/plugins/ohos/src/ohos/environment/dmlib.py index 9d4bcf7..7bffe09 100644 --- a/plugins/ohos/src/ohos/environment/dmlib.py +++ b/plugins/ohos/src/ohos/environment/dmlib.py @@ -58,7 +58,7 @@ ID_LIST = b'LIST' ID_DENT = b'DENT' DEFAULT_ENCODING = "utf-8" -COMPATIBLE_ENCODING = "ISO-8850-1" +COMPATIBLE_ENCODING = "ISO-8859-1" SYNC_DATA_MAX = 64 * 1024 REMOTE_PATH_MAX_LENGTH = 1024 SOCK_DATA_MAX = 256 diff --git a/plugins/ohos/src/ohos/executor/listener.py b/plugins/ohos/src/ohos/executor/listener.py index 34b5983..de9fdd7 100644 --- a/plugins/ohos/src/ohos/executor/listener.py +++ b/plugins/ohos/src/ohos/executor/listener.py @@ -176,14 +176,18 @@ class StackReportListener(UniversalReportListener): self._suite_name_mapping.update({suite.suite_name: suite.index}) if self.cycle > 0: suite_index = self._suite_name_mapping.get(suite.suite_name, "") - for suite_item, result_list in self.result: - if suite_item.index != suite_index: - continue - self.suites.pop(suite.index) - if result_list and result_list[-1].is_completed is not True: - result_list.pop(-1) - result_list.extend(results_of_same_suite) - break + if suite_index not in self.suite_distributions.keys(): + for suite_item, result_list in self.result: + if suite_item.index != suite_index: + continue + self.suites.pop(suite.index) + if result_list and result_list[-1].is_completed is not True: + result_list.pop(-1) + result_list.extend(results_of_same_suite) + break + else: + self.suite_distributions.update({suite.index: len(self.result)}) + self.result.append((self.suites.get(suite.index), results_of_same_suite)) else: self.suite_distributions.update({suite.index: len(self.result)}) self.result.append((self.suites.get(suite.index), results_of_same_suite))