• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""
4Copyright (c) 2021 Huawei Device Co., Ltd.
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9  http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16"""
17
18
19import os
20import sys
21import argparse
22import re
23import subprocess
24import xml.dom.minidom
25from xml.parsers.expat import ExpatError
26from string import Template
27import utils
28import json
29import shutil
30import platform
31
32
33class SuiteModuleBuilder:
34    """
35    To Build Suite Module
36    @arguments(build_target_name, target_file...)
37    """
38
39    def __init__(self, arguments):
40        self.arguments = arguments
41        self.args = None
42
43    def build_module(self):
44        """
45        build_target_name='wifiaware_test',
46        javalib_file=None,
47        project_path='xxx/communication_lite/wifiaware',
48        project_type='hctest',
49        source_path='xxx/x.c,xxx/x.c
50        subsystem_name='communication',
51        suite_filename='libwifiaware_test.a',
52        suite_out_paths='out/x/suites/acts/testcases/communication,'
53        target_file='xxxx/libs/libmodule_wifiaware_test.a',
54        test_xml='xxx/Test.json'
55        :return:
56        """
57
58        parser = argparse.ArgumentParser()
59        parser.add_argument('--build_target_name', help='', required=False)
60        parser.add_argument('--target_file', help='', required=False)
61        parser.add_argument('--hap_name', help='', required=False)
62        parser.add_argument('--project_path', help='', required=True)
63        parser.add_argument('--test_xml', help='', required=False)
64        parser.add_argument('--project_type', help='', required=True)
65        parser.add_argument('--suite_out_paths', help='', required=True)
66        parser.add_argument('--suite_filename', help='', required=True)
67        parser.add_argument('--subsystem_name', help='', required=False)
68        parser.add_argument('--build_root_path', help='', required=False)
69        parser.add_argument('--hap_sign', help='', required=False)
70        self.args = parser.parse_args(self.arguments)
71
72
73        for _suite_out_file in self.args.suite_out_paths.split(","):
74            if not _suite_out_file:
75                continue
76            if self.args.project_type == "pythontest":
77                _out_file = _suite_out_file
78            else:
79                _out_file = os.path.join(_suite_out_file,
80                                         self.args.suite_filename)
81            if self.args.project_type == "pythontest":
82                utils.copy_file(output=_out_file,
83                                source_dirs=self.args.target_file,
84                                to_dir=True)
85            elif self.args.project_type == "open_source_test":
86                utils.copy_file(output=_out_file,
87                                sources=self.args.target_file,
88                                to_dir=True)
89            elif self.args.project_type == "hjsunit":
90                utils.build_js_hap(self.args.project_path, self.args.
91                                   suite_out_paths, self.args.hap_name)
92            elif self.args.project_type != "hctest":
93                utils.copy_file(output=_out_file,
94                                sources=self.args.target_file,
95                                to_dir=False)
96
97            _testsuite_name = self.args.suite_filename
98            _matcher = re.match(r"(lib|libmodule_)?(\S+)\.\S+",
99                                _testsuite_name)
100            if _matcher:
101                _testsuite_name = _matcher.group(2)
102            if self.args.project_type != "open_source_test":
103                _config_file = os.path.join(_suite_out_file,
104                                            _testsuite_name + ".json")
105            else:
106                _config_file = os.path.join(_out_file,
107                                            _testsuite_name + ".json")
108            utils.record_testmodule_info(self.args.build_target_name,
109                                         _testsuite_name,
110                                         self.args.subsystem_name,
111                                         _suite_out_file)
112            _test_xml = self.args.test_xml
113            if _test_xml and os.path.exists(_test_xml):
114                utils.copy_file(output=_config_file, sources=_test_xml,
115                                to_dir=False)
116            else:
117                self._generate_xml_by_template(_test_xml, _testsuite_name,
118                                               _config_file)
119
120    @staticmethod
121    def _record_testmodule_info(build_target_name, module_name,
122                                subsystem_name, suite_out_dir):
123        if not build_target_name or not subsystem_name:
124            print(
125                'build_target_name or subsystem_name of testmodule "%s" '
126                'is invalid!' % module_name)
127            return
128        module_info_dir = os.path.dirname(suite_out_dir)
129        module_info_list_file = os.path.join(module_info_dir,
130                                             'module_info.json')
131        module_info_data = {}
132        if os.path.exists(module_info_list_file):
133            try:
134                with open(module_info_list_file, 'r') as module_file:
135                    module_info_data = json.load(module_file)
136            except ValueError:
137                print("NO json object could be decoded but continue")
138        module_info = {'subsystem': subsystem_name,
139                       'build_target_name': build_target_name}
140        module_info_data[module_name] = module_info
141        with open(module_info_list_file, 'w') as out_file:
142            json.dump(module_info_data, out_file)
143
144    def _generate_xml_by_template(self, test_xml, module_name,
145                                  config_file):
146        index = test_xml.rfind(".json")
147        tmpl_file = test_xml[:index] + ".tmpl"
148        if not os.path.exists(tmpl_file):
149            raise Exception(
150                "Can't find the Test.json or Test.tmpl in the "
151                "path %s " % os.path.dirname(
152                    test_xml))
153        tmpl_content = utils.read_file(tmpl_file)
154        values = {"module": module_name, "subsystem": self.args.subsystem_name}
155        xml_content = Template(tmpl_content).substitute(values)
156        utils.write_file(config_file, xml_content, False)
157
158    @staticmethod
159    def _check_file_exist(file_path):
160        if not os.path.exists(file_path):
161            raise Exception("File [%s] does not exist!" % file_path)
162
163
164class XDeviceBuilder:
165    """
166    To build XTS as a egg package
167    @arguments(project_dir, output_dirs)
168    """
169
170    def __init__(self, arguments):
171        parser = argparse.ArgumentParser()
172        parser.add_argument('--project_dir', help='', required=True)
173        parser.add_argument('--output_dirs', help='', required=True)
174        self.args = parser.parse_args(arguments)
175
176    def build_xdevice(self):
177        """
178        build xdevice package
179        :return:
180        """
181        ohos_dir = os.path.join(self.args.project_dir, 'plugins', 'ohos')
182        command = [utils.get_python_cmd(), "setup.py", "install", "--user"]
183        factory_script = os.path.join(self.args.project_dir, "factory.sh")
184        if os.path.exists(factory_script):
185            os.chmod(factory_script, 0o775)
186            command = factory_script
187        try:
188            subprocess.check_call(command, cwd=self.args.project_dir)
189            subprocess.check_call(command, cwd=ohos_dir)
190        except subprocess.CalledProcessError as exc:
191            print('returncode: {} cmd: {} output: {}'.format(
192                exc.returncode, exc.cmd, exc.output))
193
194        dist_dir = os.path.join(self.args.project_dir, 'dist')
195        ohos_dist_dir = os.path.join(ohos_dir, 'dist')
196        run_scripts = ",".join(
197            [os.path.join(self.args.project_dir, "run.bat"),
198             os.path.join(self.args.project_dir, "run.sh")])
199        config_dir = os.path.join(self.args.project_dir, "config")
200        res_dir = os.path.join(self.args.project_dir, "resource")
201        for tool_dir in self.args.output_dirs.split(","):
202            if tool_dir:
203                utils.copy_file(output=tool_dir, source_dirs=dist_dir,
204                                to_dir=True)
205                utils.copy_file(output=tool_dir, source_dirs=ohos_dist_dir,
206                                to_dir=True)
207                root_dir = os.path.dirname(tool_dir)
208                utils.copy_file(output=root_dir, sources=run_scripts,
209                                to_dir=True)
210                to_dir = os.path.join(root_dir, "config")
211                utils.copy_file(output=to_dir, source_dirs=config_dir,
212                                to_dir=True)
213                utils.copy_file(os.path.join(root_dir, "resource"),
214                                source_dirs=res_dir)
215                if not os.path.exists(os.path.join(
216                        root_dir, "resource", "tools")):
217                    os.mkdir(os.path.join(root_dir, "resource", "tools"))
218        return 0
219
220
221class SuiteArchiveBuilder:
222    def __init__(self, arguments):
223        self.module_info_dir = None
224        self.arguments = arguments
225
226    def archive_suite(self):
227        parser = argparse.ArgumentParser()
228        parser.add_argument('--suite_path', help='', required=True)
229        parser.add_argument('--build_enabled', help='', required=True)
230        args = parser.parse_args(self.arguments)
231        if not args.build_enabled.lower() == 'true':
232            print('build hit not enabled, skip making archive')
233            return 0
234
235        suite_path = args.suite_path
236        if not os.path.isdir(suite_path):
237            raise Exception("[%s] does not exist" % suite_path)
238
239        archive_name = os.path.basename(suite_path)
240        suite_root_path = os.path.dirname(suite_path)
241        shutil.make_archive(suite_path, "zip", suite_root_path, archive_name)
242        return 0
243
244
245ACTION_MAP = {"build_module": "SuiteModuleBuilder",
246              "build_xdevice": "XDeviceBuilder",
247              "archive_suite": "SuiteArchiveBuilder",
248              }
249
250
251def _find_action(action, arguments):
252    class_name = ACTION_MAP[action]
253    if not class_name:
254        raise ValueError('Unsupported operation: %s' % action)
255
256    this_module = sys.modules[__name__]
257    class_def = getattr(this_module, class_name, None)
258    if not class_def:
259        raise ValueError(
260            'Unsupported operation(No Implementation Class): %s' % action)
261    class_obj = class_def(arguments)
262    func = getattr(class_obj, action, None)
263    if not func:
264        raise ValueError(
265            'Unsupported operation(No Implementation Method): %s' % action)
266    return func
267
268
269def main(arguments):
270    action = arguments[0]
271    args = arguments[1:]
272    func = _find_action(action, args)
273    func()
274    return 0
275
276
277if __name__ == '__main__':
278    sys.exit(main(sys.argv[1:]))
279