• 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        command = [utils.get_python_cmd(), "setup.py", "install", "--user"]
182        factory_script = os.path.join(self.args.project_dir, "factory.sh")
183        if os.path.exists(factory_script):
184            os.chmod(factory_script, 0o775)
185            command = factory_script
186        try:
187            subprocess.check_call(command, cwd=self.args.project_dir)
188        except subprocess.CalledProcessError as exc:
189            print('returncode: {} cmd: {} output: {}'.format(
190                exc.returncode, exc.cmd, exc.output))
191
192        dist_dir = os.path.join(self.args.project_dir, 'dist')
193        run_scripts = ",".join(
194            [os.path.join(self.args.project_dir, "run.bat"),
195             os.path.join(self.args.project_dir, "run.sh")])
196        config_dir = os.path.join(self.args.project_dir, "config")
197        res_dir = os.path.join(self.args.project_dir, "resource")
198        for tool_dir in self.args.output_dirs.split(","):
199            if tool_dir:
200                utils.copy_file(output=tool_dir, source_dirs=dist_dir,
201                                to_dir=True)
202                root_dir = os.path.dirname(tool_dir)
203                utils.copy_file(output=root_dir, sources=run_scripts,
204                                to_dir=True)
205                to_dir = os.path.join(root_dir, "config")
206                utils.copy_file(output=to_dir, source_dirs=config_dir,
207                                to_dir=True)
208                utils.copy_file(os.path.join(root_dir, "resource"),
209                                source_dirs=res_dir)
210                if not os.path.exists(os.path.join(
211                        root_dir, "resource", "tools")):
212                    os.mkdir(os.path.join(root_dir, "resource", "tools"))
213        return 0
214
215
216class SuiteArchiveBuilder:
217    def __init__(self, arguments):
218        self.module_info_dir = None
219        self.arguments = arguments
220
221    def archive_suite(self):
222        parser = argparse.ArgumentParser()
223        parser.add_argument('--suite_path', help='', required=True)
224        parser.add_argument('--build_enabled', help='', required=True)
225        args = parser.parse_args(self.arguments)
226        if not args.build_enabled.lower() == 'true':
227            print('build hit not enabled, skip making archive')
228            return 0
229
230        suite_path = args.suite_path
231        if not os.path.isdir(suite_path):
232            raise Exception("[%s] does not exist" % suite_path)
233
234        archive_name = os.path.basename(suite_path)
235        suite_root_path = os.path.dirname(suite_path)
236        shutil.make_archive(suite_path, "zip", suite_root_path, archive_name)
237        return 0
238
239
240ACTION_MAP = {"build_module": "SuiteModuleBuilder",
241              "build_xdevice": "XDeviceBuilder",
242              "archive_suite": "SuiteArchiveBuilder",
243              }
244
245
246def _find_action(action, arguments):
247    class_name = ACTION_MAP[action]
248    if not class_name:
249        raise ValueError('Unsupported operation: %s' % action)
250
251    this_module = sys.modules[__name__]
252    class_def = getattr(this_module, class_name, None)
253    if not class_def:
254        raise ValueError(
255            'Unsupported operation(No Implementation Class): %s' % action)
256    class_obj = class_def(arguments)
257    func = getattr(class_obj, action, None)
258    if not func:
259        raise ValueError(
260            'Unsupported operation(No Implementation Method): %s' % action)
261    return func
262
263
264def main(arguments):
265    action = arguments[0]
266    args = arguments[1:]
267    func = _find_action(action, args)
268    func()
269    return 0
270
271
272if __name__ == '__main__':
273    sys.exit(main(sys.argv[1:]))
274