176e6818aSopenharmony_ci#!/usr/bin/env python3
276e6818aSopenharmony_ci# coding=utf-8
376e6818aSopenharmony_ci
476e6818aSopenharmony_ci#
576e6818aSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd.
676e6818aSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
776e6818aSopenharmony_ci# you may not use this file except in compliance with the License.
876e6818aSopenharmony_ci# You may obtain a copy of the License at
976e6818aSopenharmony_ci#
1076e6818aSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
1176e6818aSopenharmony_ci#
1276e6818aSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
1376e6818aSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
1476e6818aSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1576e6818aSopenharmony_ci# See the License for the specific language governing permissions and
1676e6818aSopenharmony_ci# limitations under the License.
1776e6818aSopenharmony_ci#
1876e6818aSopenharmony_ci
1976e6818aSopenharmony_ciimport os
2076e6818aSopenharmony_ciimport threading
2176e6818aSopenharmony_ciimport time
2276e6818aSopenharmony_ci
2376e6818aSopenharmony_cifrom devicetest.core.constants import RunResult
2476e6818aSopenharmony_cifrom devicetest.core.constants import RunSection
2576e6818aSopenharmony_cifrom devicetest.core.record import ProjectRecord
2676e6818aSopenharmony_cifrom devicetest.log.logger import DeviceTestLog as log
2776e6818aSopenharmony_cifrom devicetest.utils.time_util import TimeHandler
2876e6818aSopenharmony_cifrom devicetest.utils.util import get_base_name
2976e6818aSopenharmony_cifrom xdevice import is_env_pool_run_mode
3076e6818aSopenharmony_cifrom xdevice import Variables
3176e6818aSopenharmony_ci
3276e6818aSopenharmony_ci
3376e6818aSopenharmony_cidef get_decrypt_resource_path():
3476e6818aSopenharmony_ci    return Variables.res_dir
3576e6818aSopenharmony_ci
3676e6818aSopenharmony_ci
3776e6818aSopenharmony_cidef set_resource_path(resource_path):
3876e6818aSopenharmony_ci    DeccVariable.project.resource_path = resource_path
3976e6818aSopenharmony_ci
4076e6818aSopenharmony_ci
4176e6818aSopenharmony_cidef get_testsuit_path():
4276e6818aSopenharmony_ci    return DeccVariable.project.test_suite_path
4376e6818aSopenharmony_ci
4476e6818aSopenharmony_ci
4576e6818aSopenharmony_cidef get_project_path():
4676e6818aSopenharmony_ci    """
4776e6818aSopenharmony_ci    get project path
4876e6818aSopenharmony_ci    :return: prcject_path
4976e6818aSopenharmony_ci    """
5076e6818aSopenharmony_ci    try:
5176e6818aSopenharmony_ci        if DeccVariable.project.project_path:
5276e6818aSopenharmony_ci            return DeccVariable.project.project_path
5376e6818aSopenharmony_ci
5476e6818aSopenharmony_ci        project_path = os.path.dirname(Variables.top_dir)
5576e6818aSopenharmony_ci        if project_path is None:
5676e6818aSopenharmony_ci            log.info("project path is None.")
5776e6818aSopenharmony_ci            raise Exception("")
5876e6818aSopenharmony_ci        if not os.path.exists(project_path):
5976e6818aSopenharmony_ci            log.info("project path not exists.")
6076e6818aSopenharmony_ci            log.debug("project path:{}".format(project_path))
6176e6818aSopenharmony_ci            raise Exception("")
6276e6818aSopenharmony_ci        return project_path
6376e6818aSopenharmony_ci
6476e6818aSopenharmony_ci    except Exception as error:
6576e6818aSopenharmony_ci        raise error
6676e6818aSopenharmony_ci
6776e6818aSopenharmony_ci
6876e6818aSopenharmony_ciclass CurCase:
6976e6818aSopenharmony_ci
7076e6818aSopenharmony_ci    def __init__(self, _log):
7176e6818aSopenharmony_ci        # 用例级别参数
7276e6818aSopenharmony_ci        self.log = _log
7376e6818aSopenharmony_ci        self.step_total = 0  # tests 数
7476e6818aSopenharmony_ci        self.run_section = ""  # RunSection.SETUP
7576e6818aSopenharmony_ci        self.case_result = RunResult.PASSED  # 当前用例执行结果
7676e6818aSopenharmony_ci        self.name = ''  # 类方法名,即:用例名case_id
7776e6818aSopenharmony_ci        self.suite_name = ""  # 用例对应哪个测试套
7876e6818aSopenharmony_ci        self.error_msg = ''  # 用例失败信息
7976e6818aSopenharmony_ci        self.case_screenshot_dir = None  # 当前用例失败截图的图片保存路径
8076e6818aSopenharmony_ci        self.case_flash_error_msg = False  # 记录当前y用例是否更新了errorMsg
8176e6818aSopenharmony_ci        self.is_upload_method_result = False  # 记录当前用例是否上报过第一个失败步骤
8276e6818aSopenharmony_ci
8376e6818aSopenharmony_ci        self.step_section = RunSection.SETUP  # 用例方法setup/test/teardown
8476e6818aSopenharmony_ci        self.step_index = -1  # 当前步骤序号
8576e6818aSopenharmony_ci        self.step_error_msg = ''  # 当前步骤的失败信息
8676e6818aSopenharmony_ci        self.step_fail_msg = ''  # 用户指定的失败信息
8776e6818aSopenharmony_ci        self.step_result = RunResult.PASSED  # 当前步骤执行结果
8876e6818aSopenharmony_ci        self.steps_info = []  # 记录测试用例(含测试套子用例)的步骤信息,如步骤名称、执行结果、耗时、截图等
8976e6818aSopenharmony_ci        self.suite_steps_info = []  # 记录测试套的的步骤信息,如步骤名称、执行结果、耗时、截图等
9076e6818aSopenharmony_ci        self.auto_record_steps_info = False  # 默认记录记录用例操作步骤的信息,设为False,需人工调用record_step添加
9176e6818aSopenharmony_ci
9276e6818aSopenharmony_ci        self.test_method = TestMethod(self.log)
9376e6818aSopenharmony_ci        self.cur_check_cmd = CurCheckCmd()
9476e6818aSopenharmony_ci
9576e6818aSopenharmony_ci        # 失败截图相关
9676e6818aSopenharmony_ci        self.checkepr = False  # 啥含义?
9776e6818aSopenharmony_ci        self.image_num = 0
9876e6818aSopenharmony_ci        self.video_num = 0
9976e6818aSopenharmony_ci        self.dump_xml_num = 0
10076e6818aSopenharmony_ci
10176e6818aSopenharmony_ci        # prepare相关
10276e6818aSopenharmony_ci        self.status = 0
10376e6818aSopenharmony_ci        self.description = ''  # VAR.CurCase.Description  memoryLeakReport.py用到
10476e6818aSopenharmony_ci        self.log_details_path = "./log/test_run_details.log"
10576e6818aSopenharmony_ci        self.log_path = "./log/test_run_summary.log"
10676e6818aSopenharmony_ci        self.report_path = ''
10776e6818aSopenharmony_ci        self.iperf_path = None  # wifi相关
10876e6818aSopenharmony_ci
10976e6818aSopenharmony_ci        # windows
11076e6818aSopenharmony_ci        self.win_capture_path = ''  # WinCapturePath
11176e6818aSopenharmony_ci        self.exact_start_time = ''  # memoryLeakReport.py用到VAR.CurCase.ExactStartTime
11276e6818aSopenharmony_ci        self.start_time = ''  # memoryLeakReport.py用到VAR.CurCase.StartTime
11376e6818aSopenharmony_ci
11476e6818aSopenharmony_ci        self.case_name_file_path = ''  # VAR.CurCase.CaseName.FilePath
11576e6818aSopenharmony_ci        self.device_log = DeviceLog()
11676e6818aSopenharmony_ci
11776e6818aSopenharmony_ci        self.case_instance = None
11876e6818aSopenharmony_ci        self.suite_instance = None
11976e6818aSopenharmony_ci
12076e6818aSopenharmony_ci        self.devices = list()
12176e6818aSopenharmony_ci
12276e6818aSopenharmony_ci        self.is_capture_step_screen = False
12376e6818aSopenharmony_ci        self.is_record_step_screen = False
12476e6818aSopenharmony_ci        self.set_step_screen()
12576e6818aSopenharmony_ci
12676e6818aSopenharmony_ci    def set_step_screen(self):
12776e6818aSopenharmony_ci        if Variables.config.taskargs.get("screenrecorder", "").lower() == "true":
12876e6818aSopenharmony_ci            self.is_record_step_screen = True
12976e6818aSopenharmony_ci        else:
13076e6818aSopenharmony_ci            self.is_capture_step_screen = True
13176e6818aSopenharmony_ci
13276e6818aSopenharmony_ci    @property
13376e6818aSopenharmony_ci    def testcase(self):
13476e6818aSopenharmony_ci        return self.case_instance
13576e6818aSopenharmony_ci
13676e6818aSopenharmony_ci    @property
13776e6818aSopenharmony_ci    def testsuite(self):
13876e6818aSopenharmony_ci        return self.suite_instance
13976e6818aSopenharmony_ci
14076e6818aSopenharmony_ci    def set_case_instance(self, instance):
14176e6818aSopenharmony_ci        self.case_instance = instance
14276e6818aSopenharmony_ci        if instance:
14376e6818aSopenharmony_ci            self.devices = instance.devices
14476e6818aSopenharmony_ci
14576e6818aSopenharmony_ci    def set_suite_instance(self, instance):
14676e6818aSopenharmony_ci        self.suite_instance = instance
14776e6818aSopenharmony_ci        if instance:
14876e6818aSopenharmony_ci            self.devices = instance.devices
14976e6818aSopenharmony_ci
15076e6818aSopenharmony_ci    def set_error_msg(self, error_msg):
15176e6818aSopenharmony_ci        self.log.debug("set CurCase error msg as: {}".format(error_msg))
15276e6818aSopenharmony_ci        self.error_msg = error_msg
15376e6818aSopenharmony_ci
15476e6818aSopenharmony_ci    def set_run_section(self, run_section):
15576e6818aSopenharmony_ci        self.log.debug("set CurCase run section as: {}".format(run_section))
15676e6818aSopenharmony_ci        self.run_section = run_section
15776e6818aSopenharmony_ci
15876e6818aSopenharmony_ci    def set_case_result(self, case_result):
15976e6818aSopenharmony_ci        self.case_result = case_result
16076e6818aSopenharmony_ci        self.log.debug(
16176e6818aSopenharmony_ci            "set CurCase case result as: {}".format(self.case_result))
16276e6818aSopenharmony_ci
16376e6818aSopenharmony_ci    def set_step_total(self, step_total):
16476e6818aSopenharmony_ci        self.step_total = step_total
16576e6818aSopenharmony_ci        self.log.debug(
16676e6818aSopenharmony_ci            "set CurCase step total as: {}".format(self.step_total))
16776e6818aSopenharmony_ci
16876e6818aSopenharmony_ci    def set_name(self, name):
16976e6818aSopenharmony_ci        self.name = name
17076e6818aSopenharmony_ci        self.log.debug("set CurCase name as: {}".format(self.name))
17176e6818aSopenharmony_ci
17276e6818aSopenharmony_ci    def set_step_section(self, step_section):
17376e6818aSopenharmony_ci        self.step_section = step_section
17476e6818aSopenharmony_ci        self.log.debug(
17576e6818aSopenharmony_ci            "set CurCase step section as: {}".format(self.step_section))
17676e6818aSopenharmony_ci
17776e6818aSopenharmony_ci    def set_case_screenshot_dir(self, test_suite_path, task_report_dir, cur_case_full_path,
17876e6818aSopenharmony_ci                                repeat=1, repeat_round=1):
17976e6818aSopenharmony_ci        round_folder = f"round{repeat_round}" if repeat > 1 else ""
18076e6818aSopenharmony_ci        case_screenshot_dir = os.path.join(task_report_dir, "details", round_folder)
18176e6818aSopenharmony_ci        if is_env_pool_run_mode():
18276e6818aSopenharmony_ci            case_screenshot_dir = task_report_dir
18376e6818aSopenharmony_ci        case_abs_path_base_name = get_base_name(cur_case_full_path, is_abs_name=True)
18476e6818aSopenharmony_ci        if case_abs_path_base_name and test_suite_path:
18576e6818aSopenharmony_ci            self.log.debug("case_abs_path_base_name:{}, test_suite_path:{}"
18676e6818aSopenharmony_ci                           .format(case_abs_path_base_name, test_suite_path))
18776e6818aSopenharmony_ci            _list = case_abs_path_base_name.split(test_suite_path)
18876e6818aSopenharmony_ci            if len(_list) == 2:
18976e6818aSopenharmony_ci                case_screenshot_dir = os.path.abspath(
19076e6818aSopenharmony_ci                    os.path.join(task_report_dir, _list[1].strip(os.sep)))
19176e6818aSopenharmony_ci        self.case_screenshot_dir = case_screenshot_dir
19276e6818aSopenharmony_ci        self.log.debug("set case screenshot dir path as: {}".format(
19376e6818aSopenharmony_ci            self.case_screenshot_dir))
19476e6818aSopenharmony_ci
19576e6818aSopenharmony_ci    def init_stage_var(self, test_method_name,
19676e6818aSopenharmony_ci                       run_section=None, is_error_msg=False):
19776e6818aSopenharmony_ci        if run_section:
19876e6818aSopenharmony_ci            self.set_run_section(run_section)
19976e6818aSopenharmony_ci        self.test_method.init_test_method(test_method_name,
20076e6818aSopenharmony_ci                                          is_error_msg=is_error_msg)
20176e6818aSopenharmony_ci
20276e6818aSopenharmony_ci    def set_checkepr(self, checkepr):
20376e6818aSopenharmony_ci        self.checkepr = checkepr
20476e6818aSopenharmony_ci        self.log.debug("set project checkepr as: {}".format(self.checkepr))
20576e6818aSopenharmony_ci
20676e6818aSopenharmony_ci    def flash_error_msg_and_result(self, error_msg):
20776e6818aSopenharmony_ci        if not self.error_msg:
20876e6818aSopenharmony_ci            self.set_error_msg(error_msg)
20976e6818aSopenharmony_ci        if not self.test_method.error_msg:
21076e6818aSopenharmony_ci            self.test_method.set_error_msg(error_msg)
21176e6818aSopenharmony_ci        if self.case_result == RunResult.PASSED:
21276e6818aSopenharmony_ci            self.set_case_result(RunResult.FAILED)
21376e6818aSopenharmony_ci        if self.test_method.result == RunResult.PASSED:
21476e6818aSopenharmony_ci            self.test_method.set_result(RunResult.FAILED)
21576e6818aSopenharmony_ci
21676e6818aSopenharmony_ci    def set_step_index(self, index):
21776e6818aSopenharmony_ci        self.step_index = index
21876e6818aSopenharmony_ci
21976e6818aSopenharmony_ci    def set_step_info(self, name, **kwargs):
22076e6818aSopenharmony_ci        # 计算耗时,即前后Step记录的时间差
22176e6818aSopenharmony_ci        steps_info = self._get_steps_info_obj()
22276e6818aSopenharmony_ci        index = len(steps_info)
22376e6818aSopenharmony_ci        if index > 0:
22476e6818aSopenharmony_ci            last_step = steps_info[-1]
22576e6818aSopenharmony_ci            last_step["cost"] = round(time.time() - last_step.get("_timestamp"), 3)
22676e6818aSopenharmony_ci        log.info(f'<div class="step" id="{index}">{name}</div>')
22776e6818aSopenharmony_ci        shots = self._capture_step_screen(name)
22876e6818aSopenharmony_ci        step = {
22976e6818aSopenharmony_ci            "name": name, "error": "", "cost": 0, "screenshot": shots,
23076e6818aSopenharmony_ci            "_timestamp": time.time(), "extras": {}
23176e6818aSopenharmony_ci        }
23276e6818aSopenharmony_ci        self.__update_step_info(step, **kwargs)
23376e6818aSopenharmony_ci        steps_info.append(step)
23476e6818aSopenharmony_ci        self.set_step_index(index)
23576e6818aSopenharmony_ci        return index
23676e6818aSopenharmony_ci
23776e6818aSopenharmony_ci    def update_step_info(self, index, **kwargs):
23876e6818aSopenharmony_ci        steps_info = self._get_steps_info_obj()
23976e6818aSopenharmony_ci        max_index = len(steps_info) - 1
24076e6818aSopenharmony_ci        if not 0 <= index <= max_index:
24176e6818aSopenharmony_ci            log.warning(f"update step info failed, index must be in [0, {max_index}]")
24276e6818aSopenharmony_ci            return
24376e6818aSopenharmony_ci        step = steps_info[index]
24476e6818aSopenharmony_ci        self.__update_step_info(step, **kwargs)
24576e6818aSopenharmony_ci
24676e6818aSopenharmony_ci    def update_step_shots(self, link, name):
24776e6818aSopenharmony_ci        if not link or not name:
24876e6818aSopenharmony_ci            return
24976e6818aSopenharmony_ci        steps_info = self._get_steps_info_obj()
25076e6818aSopenharmony_ci        if len(steps_info) == 0:
25176e6818aSopenharmony_ci            return
25276e6818aSopenharmony_ci        step = steps_info[-1]
25376e6818aSopenharmony_ci        self.__update_step_info(step, screenshot={"link": link.replace("\\", "/"), "name": name})
25476e6818aSopenharmony_ci
25576e6818aSopenharmony_ci    @staticmethod
25676e6818aSopenharmony_ci    def __update_step_info(step, **kwargs):
25776e6818aSopenharmony_ci        """更新步骤的信息"""
25876e6818aSopenharmony_ci        # builtin_keys内部规定展示信息
25976e6818aSopenharmony_ci        builtin_keys = ["name", "error", "cost", "screenshot", "_timestamp"]
26076e6818aSopenharmony_ci        for k, v in kwargs.items():
26176e6818aSopenharmony_ci            if k not in builtin_keys:
26276e6818aSopenharmony_ci                step.get("extras").update({k: str(v)})
26376e6818aSopenharmony_ci                continue
26476e6818aSopenharmony_ci            if k == "error":
26576e6818aSopenharmony_ci                step.update({k: v})
26676e6818aSopenharmony_ci            elif k == "screenshot":
26776e6818aSopenharmony_ci                step.get("screenshot").append(v)
26876e6818aSopenharmony_ci
26976e6818aSopenharmony_ci    def get_steps_info(self):
27076e6818aSopenharmony_ci        steps_info = self._get_steps_info_obj()
27176e6818aSopenharmony_ci        if len(steps_info) > 0:
27276e6818aSopenharmony_ci            last_step = steps_info[-1]
27376e6818aSopenharmony_ci            last_step["cost"] = round(time.time() - last_step.get("_timestamp"), 3)
27476e6818aSopenharmony_ci        return steps_info
27576e6818aSopenharmony_ci
27676e6818aSopenharmony_ci    def _get_steps_info_obj(self):
27776e6818aSopenharmony_ci        """返回测试套或测试用例的记录表"""
27876e6818aSopenharmony_ci        return self.steps_info if self.case_instance is not None else self.suite_steps_info
27976e6818aSopenharmony_ci
28076e6818aSopenharmony_ci    def _capture_step_screen(self, step_name):
28176e6818aSopenharmony_ci        """
28276e6818aSopenharmony_ci        take a screenshot of each device after each step is performed
28376e6818aSopenharmony_ci        """
28476e6818aSopenharmony_ci        shots = []
28576e6818aSopenharmony_ci        if self.is_capture_step_screen:
28676e6818aSopenharmony_ci            from devicetest.controllers.tools.screen_agent import ScreenAgent
28776e6818aSopenharmony_ci            for device in self.devices:
28876e6818aSopenharmony_ci                path, link = ScreenAgent.capture_step_picture(TimeHandler.get_now_datetime(), step_name, device)
28976e6818aSopenharmony_ci                if not path or not os.path.exists(path):
29076e6818aSopenharmony_ci                    continue
29176e6818aSopenharmony_ci                shots.append({"link": link.replace("\\", "/"), "name": step_name})
29276e6818aSopenharmony_ci        return shots
29376e6818aSopenharmony_ci
29476e6818aSopenharmony_ci
29576e6818aSopenharmony_ciclass TestMethod:
29676e6818aSopenharmony_ci    def __init__(self, _log):
29776e6818aSopenharmony_ci        # 步骤级别参数
29876e6818aSopenharmony_ci        self.log = _log
29976e6818aSopenharmony_ci        self.name = 'setup'
30076e6818aSopenharmony_ci        self.result = RunResult.PASSED
30176e6818aSopenharmony_ci        self.level = ''
30276e6818aSopenharmony_ci        self.error_msg = ''
30376e6818aSopenharmony_ci        self.method_return = ''
30476e6818aSopenharmony_ci        self.func_ret = []
30576e6818aSopenharmony_ci        self.step_flash_fail_msg = False
30676e6818aSopenharmony_ci
30776e6818aSopenharmony_ci    def set_result(self, result=None):
30876e6818aSopenharmony_ci        self.result = result or RunResult.PASSED
30976e6818aSopenharmony_ci        self.log.debug(
31076e6818aSopenharmony_ci            "set TestMethod result as: {}".format(self.result))
31176e6818aSopenharmony_ci
31276e6818aSopenharmony_ci    def set_error_msg(self, error_msg):
31376e6818aSopenharmony_ci        self.error_msg = error_msg
31476e6818aSopenharmony_ci        self.log.debug(
31576e6818aSopenharmony_ci            "set TestMethod error msg as: {}".format(self.error_msg))
31676e6818aSopenharmony_ci
31776e6818aSopenharmony_ci    def init_test_method(self, name, is_error_msg=False):
31876e6818aSopenharmony_ci        self.level = '',
31976e6818aSopenharmony_ci        self.name = name,
32076e6818aSopenharmony_ci        self.result = RunResult.PASSED
32176e6818aSopenharmony_ci        if is_error_msg:
32276e6818aSopenharmony_ci            self.error_msg = ''
32376e6818aSopenharmony_ci        self.func_ret.clear()
32476e6818aSopenharmony_ci
32576e6818aSopenharmony_ci    def init_aw_method(self):
32676e6818aSopenharmony_ci        self.error_msg = ''
32776e6818aSopenharmony_ci        self.result = RunResult.PASSED
32876e6818aSopenharmony_ci        self.step_flash_fail_msg = False  # 记录当前步骤是否更新了failMsg
32976e6818aSopenharmony_ci        self.func_ret.clear()
33076e6818aSopenharmony_ci        self.log.debug("init aw method.")
33176e6818aSopenharmony_ci
33276e6818aSopenharmony_ci
33376e6818aSopenharmony_ciclass CurStep:
33476e6818aSopenharmony_ci    pass
33576e6818aSopenharmony_ci
33676e6818aSopenharmony_ci
33776e6818aSopenharmony_ciclass Prepare:
33876e6818aSopenharmony_ci    def __init__(self):
33976e6818aSopenharmony_ci        self.path = ''
34076e6818aSopenharmony_ci        self.config = {}
34176e6818aSopenharmony_ci
34276e6818aSopenharmony_ci    def set_prepare_path(self, path):
34376e6818aSopenharmony_ci        if path:
34476e6818aSopenharmony_ci            self.path = path
34576e6818aSopenharmony_ci        log.debug("prepare path:{}".format(path))
34676e6818aSopenharmony_ci
34776e6818aSopenharmony_ci
34876e6818aSopenharmony_ciclass Settings:
34976e6818aSopenharmony_ci    language = ''
35076e6818aSopenharmony_ci    product = ''  # VAR.Settings.Product
35176e6818aSopenharmony_ci
35276e6818aSopenharmony_ci
35376e6818aSopenharmony_ciclass Event:
35476e6818aSopenharmony_ci    configs = {}  # VAR.Event.Configs
35576e6818aSopenharmony_ci
35676e6818aSopenharmony_ci
35776e6818aSopenharmony_ciclass RedirectLog:
35876e6818aSopenharmony_ci    task_name = ""  # VAR.Project.RedirectLog.TaskName
35976e6818aSopenharmony_ci
36076e6818aSopenharmony_ci
36176e6818aSopenharmony_ciclass DeviceLog:
36276e6818aSopenharmony_ci    ftp_path = []  # VAR.CurCase.DeviceLog.FthPath
36376e6818aSopenharmony_ci
36476e6818aSopenharmony_ci
36576e6818aSopenharmony_ciclass ProjectVariables:
36676e6818aSopenharmony_ci    def __init__(self, _log):
36776e6818aSopenharmony_ci        # 工程级别参数
36876e6818aSopenharmony_ci        self.log = _log
36976e6818aSopenharmony_ci        self.record = ProjectRecord(_log)
37076e6818aSopenharmony_ci        self.project_path = ''  # xdevice工程路径
37176e6818aSopenharmony_ci        self.aw_path = ''  # 测试套aw路径
37276e6818aSopenharmony_ci        self.testcase_path = ''
37376e6818aSopenharmony_ci        self.settings = None
37476e6818aSopenharmony_ci        self.resource_path = ''  # 测试套工程resource路径
37576e6818aSopenharmony_ci        self.test_suite_path = ''  # 测试套工程路径
37676e6818aSopenharmony_ci        self.task_report_dir = ''  # 测试用例的框架日志路径
37776e6818aSopenharmony_ci        self.prepare = Prepare()  # prepare 相关
37876e6818aSopenharmony_ci        self.cur_case_full_path = ''  # 记录当前正执行用例全路径
37976e6818aSopenharmony_ci        self.execute_case_name = None  # 记录当前正执行用例id
38076e6818aSopenharmony_ci        self.config_json = {}  # 用户自定义的公共的参数
38176e6818aSopenharmony_ci        self.property_config = []  # 用户自定义的设备相关的参数
38276e6818aSopenharmony_ci        self.retry_test_list = []
38376e6818aSopenharmony_ci        self.devicename = {}
38476e6818aSopenharmony_ci        self.step_debug = ''
38576e6818aSopenharmony_ci
38676e6818aSopenharmony_ci        self.monkey = False  # extension/monkey/monkey.py VAR.Project.Monkey
38776e6818aSopenharmony_ci        self.task_id = ""  # VAR.Project.TaskID memoryLeakReport.py中用到,先记录该字段 VAR。Projec.TaskId
38876e6818aSopenharmony_ci        self.settings = Settings()  # target中用到:VAR。Settings.Language
38976e6818aSopenharmony_ci        self.total = 0  # VAR.Project.Total
39076e6818aSopenharmony_ci        self.start_time = ''  # memoryLeakReport.py用到VAR.Project.StartTime
39176e6818aSopenharmony_ci        self.exact_start_time = ''  # memoryLeakReport.py用到VAR.Project.ExactStartTime
39276e6818aSopenharmony_ci        self.finish = 0  # VAR.Project.Finish
39376e6818aSopenharmony_ci
39476e6818aSopenharmony_ci        self.config = {
39576e6818aSopenharmony_ci        }
39676e6818aSopenharmony_ci
39776e6818aSopenharmony_ci        self.event = Event()
39876e6818aSopenharmony_ci        self.test_file = ''  # VAR.Project.TestFile
39976e6818aSopenharmony_ci        self.is_ticc_server = False  # GlobalParam.IS_TICC_SERVER
40076e6818aSopenharmony_ci        self.redirect_log = RedirectLog()
40176e6818aSopenharmony_ci
40276e6818aSopenharmony_ci    def set_project_path(self, project_path=None):
40376e6818aSopenharmony_ci        self.project_path = project_path or get_project_path()
40476e6818aSopenharmony_ci        self.log.debug("project path is: {}".format(self.project_path))
40576e6818aSopenharmony_ci
40676e6818aSopenharmony_ci    def set_aw_path(self, aw_path):
40776e6818aSopenharmony_ci        if aw_path:
40876e6818aSopenharmony_ci            self.aw_path = aw_path
40976e6818aSopenharmony_ci            self.log.debug("aw path is: {}".format(self.aw_path))
41076e6818aSopenharmony_ci
41176e6818aSopenharmony_ci    def set_testcase_path(self, testcase_path):
41276e6818aSopenharmony_ci        self.testcase_path = testcase_path
41376e6818aSopenharmony_ci        self.log.debug("testcase path is: {}".format(self.testcase_path))
41476e6818aSopenharmony_ci
41576e6818aSopenharmony_ci    def set_settings(self, settings):
41676e6818aSopenharmony_ci        if settings:
41776e6818aSopenharmony_ci            self.settings = settings
41876e6818aSopenharmony_ci        self.log.debug("settings is: {}".format(self.settings))
41976e6818aSopenharmony_ci
42076e6818aSopenharmony_ci    def set_test_suite_path(self, test_suite_path):
42176e6818aSopenharmony_ci        if test_suite_path:
42276e6818aSopenharmony_ci            self.test_suite_path = test_suite_path
42376e6818aSopenharmony_ci        self.log.debug("test suite path is: {}".format(self.test_suite_path))
42476e6818aSopenharmony_ci
42576e6818aSopenharmony_ci    def set_task_report_dir(self, task_report_dir):
42676e6818aSopenharmony_ci        if task_report_dir:
42776e6818aSopenharmony_ci            self.task_report_dir = task_report_dir
42876e6818aSopenharmony_ci        self.log.debug("task report dir: {}".format(self.task_report_dir))
42976e6818aSopenharmony_ci
43076e6818aSopenharmony_ci    def set_resource_path(self, resource_path):
43176e6818aSopenharmony_ci        if resource_path:
43276e6818aSopenharmony_ci            self.resource_path = resource_path
43376e6818aSopenharmony_ci        self.log.debug("resource path is: {}".format(self.resource_path))
43476e6818aSopenharmony_ci
43576e6818aSopenharmony_ci    def set_config_json(self, config_json):
43676e6818aSopenharmony_ci        self.config_json = config_json
43776e6818aSopenharmony_ci        self.log.debug("config json is: {}".format(self.config_json))
43876e6818aSopenharmony_ci
43976e6818aSopenharmony_ci    def set_property_config(self, property_config):
44076e6818aSopenharmony_ci        self.property_config = property_config
44176e6818aSopenharmony_ci        self.log.debug("property config is: {}".format(self.property_config))
44276e6818aSopenharmony_ci
44376e6818aSopenharmony_ci    def set_devicename(self, devicename):
44476e6818aSopenharmony_ci        if devicename:
44576e6818aSopenharmony_ci            self.devicename = devicename
44676e6818aSopenharmony_ci        self.log.debug("devicename is: {}".format(self.devicename))
44776e6818aSopenharmony_ci
44876e6818aSopenharmony_ci
44976e6818aSopenharmony_ciclass CurCheckCmd:
45076e6818aSopenharmony_ci    def __init__(self):
45176e6818aSopenharmony_ci        # 用例校验参数?
45276e6818aSopenharmony_ci        self.through = ""
45376e6818aSopenharmony_ci        self.expect = ""
45476e6818aSopenharmony_ci        self.actual = ""
45576e6818aSopenharmony_ci
45676e6818aSopenharmony_ci    def get_cur_check_status(self):
45776e6818aSopenharmony_ci        if all([self.through, self.expect, self.actual]):
45876e6818aSopenharmony_ci            return True
45976e6818aSopenharmony_ci        return False
46076e6818aSopenharmony_ci
46176e6818aSopenharmony_ci    def get_cur_check_msg(self):
46276e6818aSopenharmony_ci        return "{}, expect:{}, actual:{}".format(self.through, self.expect,
46376e6818aSopenharmony_ci                                                 self.actual)
46476e6818aSopenharmony_ci
46576e6818aSopenharmony_ci
46676e6818aSopenharmony_ciclass DeccVariable:
46776e6818aSopenharmony_ci    __cur_case = {}
46876e6818aSopenharmony_ci    __thread_lock = threading.Lock()
46976e6818aSopenharmony_ci    project = ProjectVariables(log)
47076e6818aSopenharmony_ci
47176e6818aSopenharmony_ci    @classmethod
47276e6818aSopenharmony_ci    def set_project_obj(cls, project_obj):
47376e6818aSopenharmony_ci        log.info("init DeccVariable project object")
47476e6818aSopenharmony_ci        cls.project = project_obj
47576e6818aSopenharmony_ci
47676e6818aSopenharmony_ci    @classmethod
47776e6818aSopenharmony_ci    def set_cur_case_obj(cls, cur_case_obj):
47876e6818aSopenharmony_ci        log.info("init DeccVariable cur case object")
47976e6818aSopenharmony_ci        with cls.__thread_lock:
48076e6818aSopenharmony_ci            cls.__cur_case[cls.__cur_case_key()] = cur_case_obj
48176e6818aSopenharmony_ci
48276e6818aSopenharmony_ci    @classmethod
48376e6818aSopenharmony_ci    def cur_case(cls):
48476e6818aSopenharmony_ci        with cls.__thread_lock:
48576e6818aSopenharmony_ci            return cls.__cur_case.get(cls.__cur_case_key(), None)
48676e6818aSopenharmony_ci
48776e6818aSopenharmony_ci    @classmethod
48876e6818aSopenharmony_ci    def __cur_case_key(cls):
48976e6818aSopenharmony_ci        return threading.current_thread().ident
49076e6818aSopenharmony_ci
49176e6818aSopenharmony_ci    @classmethod
49276e6818aSopenharmony_ci    def reset(cls):
49376e6818aSopenharmony_ci        log.info("reset DeccVariable")
49476e6818aSopenharmony_ci        with cls.__thread_lock:
49576e6818aSopenharmony_ci            key = cls.__cur_case_key()
49676e6818aSopenharmony_ci            if key in cls.__cur_case:
49776e6818aSopenharmony_ci                cls.__cur_case.pop(key)
498