• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3
4#
5# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import os
20import sys
21import json
22import shutil
23import subprocess
24import platform
25
26from xdevice import platform_logger
27from core.utils import get_build_output_path
28from core.utils import scan_support_product
29from core.common import is_open_source_product
30from core.config.config_manager import UserConfigManager
31
32BUILD_FILEPATH = "./build.sh"
33BUILD_LITE = "build/lite/build.py"
34BUILD_TARGET_PLATFORM = "build_platform=\"%s\""
35BUILD_PRODUCT_NAME = "product_name=%s"
36BUILD_TARGET_SUBSYSTEM = "target_subsystem=%s"
37BUILD_TARGET_SUITE = "suite=%s"
38LOG = platform_logger("BuildTestcases")
39
40
41##############################################################################
42##############################################################################
43
44class BuildTestcases(object):
45    def __init__(self, project_rootpath):
46        self.project_rootpath = project_rootpath
47        self.xts_project_rootpath = os.path.join(sys.source_code_root_path,
48                                                 "test",
49                                                 "xts",
50                                                 "acts")
51        user_manager = UserConfigManager()
52        self.is_build_example = user_manager.get_user_config_flag(
53            "build", "example")
54        self.build_parameter_dic = user_manager.get_user_config(
55            "build", "parameter")
56
57    @classmethod
58    def _copy_folder(cls, source_dir, target_dir):
59        if not os.path.exists(target_dir):
60            os.makedirs(target_dir)
61
62        if platform.system() == 'Windows':
63            command = ["xcopy", "/f", "/s", "/e", "/y",
64                       "/b", "/q", source_dir, target_dir]
65        else:
66            command = ["cp", "-rf", source_dir, target_dir]
67
68        LOG.info("command: %s" % str(command))
69        return subprocess.call(command) == 0
70
71    @classmethod
72    def _get_testcase_outname_by_productform(cls, productform):
73        if productform == "phone" or is_open_source_product(productform):
74            return ""
75
76        testcase_outpath = ""
77
78        # 路径注释 get_build_output_path = OpenHarmony/out/rk3568/build_configs/platforms_info/toolchain_to_variant.json
79        toolchain_filepath = os.path.join(
80            get_build_output_path(productform),
81            "build_configs",
82            "platforms_info",
83            "toolchain_to_variant.json")
84        if os.path.exists(toolchain_filepath):
85            data_dic = []
86            with open(toolchain_filepath, 'r') as toolchain_file:
87                data_dic = json.load(toolchain_file)
88                if not data_dic:
89                    LOG.warning("The %s file load error." %
90                                toolchain_filepath)
91                    data_dic = []
92            paltform_toolchain_dic = data_dic.get("platform_toolchain")
93            testcase_outpath = paltform_toolchain_dic.get(productform, "")
94            pos = testcase_outpath.rfind(':') + 1
95            testcase_outpath = testcase_outpath[pos:len(testcase_outpath)]
96        return testcase_outpath
97
98    @classmethod
99    def _delete_acts_testcase_dir(cls, productform):
100        acts_testcase_out_dir = os.path.join(
101            get_build_output_path(productform),
102            "suites",
103            "acts",
104            "testcases")
105        LOG.info("acts_testcase_out_dir=%s" % acts_testcase_out_dir)
106        # 删除~/OpenHarmony/out/rk3568/suites/acts/testcases目录内容
107        if os.path.exists(acts_testcase_out_dir):
108            shutil.rmtree(acts_testcase_out_dir)
109
110    def _delete_testcase_dir(self, productform):
111        if is_open_source_product(productform):
112            package_out_dir = os.path.join(
113                get_build_output_path(productform),
114                "packages",
115                "phone",
116                "tests")
117        else:
118            package_out_dir = os.path.join(
119                get_build_output_path(productform),
120                "packages",
121                productform,
122                "tests")
123
124        LOG.info("package_out_dir=%s" % package_out_dir)
125        # 删除~/OpenHarmony/out/rk3568/packages/phone/tests目录内容
126        if os.path.exists(package_out_dir):
127            shutil.rmtree(package_out_dir)
128
129        phone_out_dir = os.path.join(
130            self.project_rootpath, "out", "release", "tests")
131        LOG.info("phone_out_dir=%s" % phone_out_dir)
132        # 删除~/OpenHarmony/out/release/tests目录内容
133        if os.path.exists(phone_out_dir):
134            shutil.rmtree(phone_out_dir)
135
136        curr_productform_outname = self._get_testcase_outname_by_productform(
137            productform)
138        if curr_productform_outname == "":
139            return
140
141        curr_productform_outdir = os.path.join(
142            get_build_output_path(productform),
143            curr_productform_outname,
144            "tests")
145        LOG.info("curr_productform_outdir=%s" % curr_productform_outdir)
146        if os.path.exists(curr_productform_outdir):
147            shutil.rmtree(curr_productform_outdir)
148
149    def _merge_testcase_dir(self, productform):
150        if is_open_source_product(productform):
151            package_out_dir = os.path.join(
152                get_build_output_path(productform),
153                "packages",
154                "phone")
155        else:
156            package_out_dir = os.path.join(
157                get_build_output_path(productform),
158                "packages",
159                productform)
160        if platform.system() == 'Windows':
161            package_out_dir = os.path.join(package_out_dir, "tests")
162
163        phone_out_dir = os.path.join(get_build_output_path(productform),
164                                     "tests")
165        if os.path.exists(phone_out_dir):
166            self._copy_folder(phone_out_dir, package_out_dir)
167
168        curr_productform_outname = self._get_testcase_outname_by_productform(
169            productform)
170        if curr_productform_outname == "":
171            return
172
173        curr_productform_outdir = os.path.join(
174            get_build_output_path(productform),
175            curr_productform_outname,
176            "tests")
177        LOG.info("curr_productform_outdir=%s" % curr_productform_outdir)
178        if os.path.exists(curr_productform_outdir):
179            self._copy_folder(curr_productform_outdir, package_out_dir)
180
181    def _execute_build_command(self, productform, command):
182        build_result = False
183        current_path = os.getcwd()
184        os.chdir(self.project_rootpath)
185
186        command.append("--product-name")
187        command.append(productform)
188
189        if os.path.exists(BUILD_FILEPATH):
190            build_command = [BUILD_FILEPATH]
191            build_command.extend(command)
192            LOG.info("build_command: %s" % str(build_command))
193            if subprocess.call(build_command) == 0:
194                build_result = True
195            else:
196                build_result = False
197        else:
198            LOG.warning("Error: The %s is not exist" % BUILD_FILEPATH)
199
200        os.chdir(current_path)
201        return build_result
202
203    def _execute_build_acts_command(self, para):
204        build_result = False
205        acts_build_command = []
206        current_path = os.getcwd()
207        # 路径 acts_rootpath = ~/OpenHarmony/test/xts/acts
208        os.chdir(self.xts_project_rootpath)
209        acts_build_command.append(BUILD_PRODUCT_NAME % para.productform)
210        acts_build_command.append("system_size=standard")
211        if len(para.subsystem) > 0:
212            input_subsystem = ",".join(para.subsystem)
213            acts_build_command.append(BUILD_TARGET_SUBSYSTEM % input_subsystem)
214        if para.testsuit != "" and len(para.subsystem) == 0:
215            LOG.error("Please specify subsystem.")
216            return
217        target_cpu = self.build_parameter_dic.get("target_cpu")
218        if target_cpu == "arm64":
219            acts_build_command.append("target_arch=" + target_cpu)
220        if os.path.exists(BUILD_FILEPATH):
221            build_command = [BUILD_FILEPATH]
222            build_command.extend(acts_build_command)
223            LOG.info("build_acts_command: %s" % str(build_command))
224            if subprocess.call(build_command) == 0:
225                build_result = True
226            else:
227                build_result = False
228        else:
229            LOG.warning("Build Acts Testcase Error: The %s is not exist" % BUILD_FILEPATH)
230
231        os.chdir(current_path)
232        return build_result
233
234    def build_fuzz_testcases(self, para):
235        self._delete_testcase_dir(para.productform)
236        helper_path = os.path.join("..", "libs", "fuzzlib", "fuzzer_helper.py")
237        command = [sys.executable, helper_path, 'make',
238                   'make_temp_test', para.productform]
239        if subprocess.call(command, shell=False) == 0:
240            build_result = True
241        else:
242            build_result = False
243        self._merge_testcase_dir(para.productform)
244        return build_result
245
246    # 编译测试用例(编译命令拼接)
247    def build_testcases(self, productform, target):
248        command = []
249        if self.is_build_example:
250            command.append("--gn-args")
251            command.append("build_example=true")
252        command.append("--build-target")
253        command.append(target)
254        target_cpu = self.build_parameter_dic.get("target_cpu")
255        if target_cpu == "arm64":
256            if productform == "m40":
257                command.append("--gn-args")
258                command.append("use_musl=false")
259                command.append("--gn-args")
260                command.append("use_custom_libcxx=true")
261                command.append("--gn-args")
262                command.append("use_custom_clang=true")
263            command.append("--target-cpu")
264            command.append(target_cpu)
265        command.append("--ccache")
266        self._delete_testcase_dir(productform)
267        build_result = self._execute_build_command(productform, command)
268        self._merge_testcase_dir(productform)
269        return build_result
270
271    # 编译ACTS测试用例
272    def build_acts_testcases(self, para):
273        self._delete_acts_testcase_dir(para.productform)
274        build_result = self._execute_build_acts_command(para)
275        return build_result
276
277    def build_gn_file(self, productform):
278        command = []
279        if self.is_build_example:
280            command.append("--gn-args")
281            command.append("build_example=true")
282        command.append("--build-only-gn")
283        command.append("--gn-args")
284        command.append(BUILD_TARGET_PLATFORM % productform)
285        return self._execute_build_command(productform, command)
286
287    def build_version(self, productform):
288        command = []
289        command.append("--build-target")
290        command.append("make_all")
291        command.append("--gn-args")
292        command.append(BUILD_TARGET_PLATFORM % productform)
293        return self._execute_build_command(productform, command)
294
295
296##############################################################################
297##############################################################################
298