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