• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
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
18import os
19import fnmatch
20import sys
21import argparse
22import json
23import platform
24import subprocess
25
26import distutils.dir_util as dir_util
27import distutils.file_util as file_util
28from distutils.errors import DistutilsError
29
30
31# all sub system list, must be lowercase.
32_SUB_SYSTEM_LIST = [
33    "kernel",
34    "hiviewdfx",
35    "communication",
36    "security",
37    "update",
38    "sstsutils",
39    "commonlibrary",
40    "multimedia",
41    "hdf",
42    "ability",
43    "appexecfwk",
44    "distributed_schedule",
45    "startup",
46    "sensors",
47    "sample",
48    "iothardware",
49    "open_posix_testsuite",
50    "graphic",
51    "ace",
52    "applications",
53    "ai",
54    "global",
55    "telephony",
56    "dcts",
57    "distributeddatamgr"
58]
59
60_NO_FILTE_SUB_SYSTEM_LIST = [
61    "appexecfwk",
62    "applications",
63    "kernel",
64    "open_posix_testsuite",
65    "sample",
66    "telephony",
67    "dcts",
68    "hiviewdfx",
69    "security",
70    "update",
71    "sstsutils",
72    "hdf",
73    "distributed_schedule"
74]
75
76
77def main():
78    parser = argparse.ArgumentParser()
79    parser.add_argument('--method_name', help='', required=True)
80    parser.add_argument('--arguments', help='',
81                        required=True)  # format key=value#key=value
82    args = parser.parse_args()
83    this_module = sys.modules[__name__]
84    method = getattr(this_module, args.method_name)
85    arguments = {}
86    for argument in args.arguments.split("#"):
87        key_value = argument.strip().split("=")
88        if len(key_value) != 2:
89            raise ValueError(
90                "The arguments' format is 'key=value#key=value'. Wrong format:"
91                " {}".format(argument))
92        arguments.setdefault(key_value[0].strip(), key_value[1].strip())
93    method(**arguments)
94    return 0
95
96
97def read_file(input_file):
98    if not os.path.exists(input_file):
99        return ""
100
101    with open(input_file, 'r') as input_f:
102        content = input_f.read().strip()
103        return content
104
105
106def write_file(output_file, content, append):
107    file_dir = os.path.dirname(os.path.abspath(output_file))
108    if not os.path.exists(file_dir):
109        os.makedirs(file_dir)
110    mode = 'a+' if append else 'w'
111    with open(output_file, mode) as output_f:
112        output_f.write("%s\n" % content)
113
114
115def copy_file(output, sources="", source_dirs="", to_dir=True):
116    """
117    copy source files or source dir to output.
118    if sources is not empty, the output can be file(will be created
119    automatically)
120    or directory(must be exist).
121    :param output: If source_dirs is not empty, output must be directory.
122    :param sources: source files is separated by dot
123    :param source_dirs: source directory is separated by dot
124    :param to_dir: output is directory or not
125    :return:
126    """
127    if not sources and not source_dirs:
128        raise Exception(
129            "sources or source_dirs parameter must be specified one")
130    _output = output.strip()
131    _sources = sources.strip()
132    _source_dirs = source_dirs.strip()
133    _parent_output = os.path.dirname(_output)
134    try:
135        if to_dir and not os.path.exists(_output):
136            os.makedirs(_output)
137        if not to_dir and not os.path.exists(_parent_output):
138            os.makedirs(_parent_output)
139    except OSError:
140        if not os.path.isdir(_output):
141            raise
142    try:
143        if _sources:
144            _copy_files(_sources.split(","), _output)
145
146        if _source_dirs:
147            _copy_dir(_source_dirs.split(","), _output)
148    except DistutilsError:
149        print("ignore file exist error")
150    return 0
151
152
153def _copy_files(sources, output):
154    copy_set = set()
155    for source_file in sources:
156        source_file = source_file.strip()
157        if os.path.isfile(source_file) and os.path.exists(source_file):
158            # if same file name exist, add dir path
159            if os.path.basename(source_file) in copy_set:
160                new_output = os.path.join(output, os.path.dirname(source_file).
161                                          split(os.sep)[-1])
162                if not os.path.exists(new_output):
163                    os.makedirs(new_output)
164                file_util.copy_file(source_file, new_output)
165            else:
166                file_util.copy_file(source_file, output)
167            copy_set.add(os.path.basename(source_file))
168
169
170def _copy_dir(sources, output):
171    for source_file in sources:
172        source_file = source_file.strip()
173        if os.path.isdir(source_file):
174            dir_util.copy_tree(source_file, output)
175
176
177def gen_suite_out(suite_output_prefix, suite_names, out_suffix):
178    outputs = []
179    _suite_output_prefix = suite_output_prefix.strip()
180    _dirname_suffix = out_suffix.strip().rstrip(os.sep)
181    for suite in suite_names.split(","):
182        path = "%s%s/%s" % (
183            _suite_output_prefix, suite.strip(), _dirname_suffix)
184        outputs.append(path)
185        print(path)
186    return outputs
187
188
189def get_subsystem_name(path):
190    subsystem_name = ""
191    for subsystem in _SUB_SYSTEM_LIST:
192        subsystem_path = "/{}/".format(subsystem)
193        _path = path.lower()
194        if subsystem_path in _path:
195            subsystem_name = subsystem
196            break
197        subsystem_path = "/{}_lite/".format(subsystem)
198        if subsystem_path in _path:
199            subsystem_name = subsystem
200            break
201    sys.stdout.write(subsystem_name)
202    return subsystem_name
203
204
205def get_modulename_by_buildtarget(module_list_file, build_target):
206    if not os.path.exists(module_list_file):
207        return ""
208    with open(module_list_file, "r") as module_file:
209        module_info_data = json.load(module_file)
210    for module in module_info_data:
211        if module_info_data[module]["build_target_name"] == build_target:
212            sys.stdout.write(module)
213            return module
214    return ""
215
216
217def glob(path, filename_pattern):
218    files = []
219    for dir_path, _, files in os.walk(path):
220        for filename in fnmatch.filter(files, filename_pattern):
221            files.append(os.path.join(dir_path, filename))
222    return files
223
224
225def filter_by_subsystem(testsuites, product_json):
226    product_info = {}
227    filtered_features = []
228    subs_comps = {}
229    # parses product json to obtain all the subsystem name
230    if os.path.exists(product_json):
231        try:
232            with open(product_json, 'r') as product_info:
233                product_info = json.load(product_info)
234        except ValueError:
235            print("NO json object could be decoded.")
236        subsystem_info = product_info.get("subsystems")
237        for subsystem in subsystem_info:
238            subs_comps[subsystem.get("subsystem")] = \
239                subsystem.get("components", [])
240
241    feature_list = testsuites.split(",")
242    for feature in feature_list:
243        # if subsytem name match
244        subsystem = get_subsystem_name_no_output(feature)
245        if subsystem in _NO_FILTE_SUB_SYSTEM_LIST:
246            filtered_features.append(feature)
247            print(feature)
248        elif subsystem in subs_comps:
249            components = subs_comps.get(subsystem, [])
250            if check_component(feature, components):
251                filtered_features.append(feature)
252                print(feature)
253    return filtered_features
254
255
256def get_subsystem_name_no_output(path):
257    subsystem_name = ""
258    for subsystem in _SUB_SYSTEM_LIST:
259        subsystem_path = "/{}".format(subsystem)
260        _path = path.lower()
261        if subsystem_path in _path:
262            subsystem_name = subsystem
263            break
264        subsystem_path = "/{}_lite".format(subsystem)
265        if subsystem_path in _path:
266            subsystem_name = subsystem
267            break
268    return subsystem_name
269
270
271def check_component(path, components):
272    for component in components:
273        component_name = component.get("component", "")
274        if component_name != "kv_store_lite":
275            component_name = component_name.replace("_lite", "")
276        if component_name in path or "{}_hal".format(component_name) in path \
277                 or "{}_posix".format(component_name) in path:
278            return True
279    return False
280
281
282def get_python_cmd():
283    major, _, _ = platform.python_version_tuple()
284    if major == "3":
285        return "python"
286    else:
287        return "python3"
288
289
290def record_testmodule_info(build_target_name, module_name,
291                           subsystem_name, suite_out_dir, same_file=False):
292    if not build_target_name or not subsystem_name:
293        print(
294            'build_target_name or subsystem_name of testmodule "%s" '
295            'is invalid!' % module_name)
296        return
297    if same_file:
298        module_info_list_file = os.path.join(suite_out_dir, 'module_info.json')
299    else:
300        module_info_list_file = os.path.join(suite_out_dir,
301                                             '{}_module_info.json'.format
302                                             (build_target_name))
303    module_info_data = {}
304    if os.path.exists(module_info_list_file):
305        try:
306            with open(module_info_list_file, 'r') as module_file:
307                module_info_data = json.load(module_file)
308        except ValueError:
309            print("NO json object could be decoded but continue")
310    module_info = {'subsystem': subsystem_name,
311                   'build_target_name': build_target_name}
312    module_info_data[module_name] = module_info
313    with open(module_info_list_file, 'w') as out_file:
314        json.dump(module_info_data, out_file)
315
316
317def record_test_component_info(out_dir, version):
318    if not os.path.exists(out_dir):
319        os.makedirs(out_dir)
320    all_module_file = os.path.join(out_dir, 'module_info.json')
321    all_module_data = {}
322    for root, dirs, files in os.walk(out_dir):
323        for file in files:
324            if file.endswith("module_info.json"):
325                with open(os.path.join(root, file), 'r') as json_data:
326                    module_data = json.load(json_data)
327                    all_module_data.update(module_data)
328                os.remove(os.path.join(root, file))
329    with open(all_module_file, 'w') as out_file:
330        json.dump(all_module_data, out_file)
331
332    test_component_file = os.path.join(out_dir, 'test_component.json')
333    test_component_data = {'version': version, }
334    with open(test_component_file, 'w') as out_file:
335        json.dump(test_component_data, out_file)
336
337
338def get_target_modules(all_features):
339    feature_list = []
340    if all_features:
341        for feature in all_features.split(","):
342            if feature:
343                feature_list.append(feature)
344                print(feature)
345    return feature_list
346
347
348def cmd_popen(cmd):
349    proc = subprocess.Popen(cmd)
350    proc.wait()
351    ret_code = proc.returncode
352    if ret_code != 0:
353        raise Exception("{} failed, return code is {}".format(cmd, ret_code))
354
355
356def build_js_hap(project_path, out_put_dir, hap_name):
357    if not check_env():
358        return
359    gradle_dir = os.path.join(project_path, "gradle")
360    os.chdir(gradle_dir)
361    build_clean = ["gradle", "clean"]
362    cmd_popen(build_clean)
363    build_cmd = ["gradle", "entry:packageDebugHap"]
364    cmd_popen(build_cmd)
365    gralde_output_dir = os.path.join(gradle_dir, "entry", "build", "outputs")
366    if os.path.exists(gralde_output_dir):
367        for root, _, files in os.walk(gralde_output_dir):
368            for file in files:
369                if file.endswith(".hap"):
370                    file_util.copy_file(os.path.join(root, file),
371                                        os.path.join(out_put_dir.rstrip(','),
372                                                     hap_name))
373                    return
374
375
376
377def check_env():
378    """
379    check all the env for js hap build
380    return: return true if all env ready, otherwise return false
381    """
382    env_list = ['OHOS_SDK_HOME', 'NODE_HOME', 'GRADLE_HOME']
383    for env in env_list:
384        if not os.environ.get(env):
385            print("the env {} not set, skip build!".format(env))
386            return False
387    else:
388        return True
389if __name__ == '__main__':
390    sys.exit(main())
391