• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2023 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17
18import shutil
19import subprocess
20import os
21import sys
22import inspect
23import pytest
24import json
25
26from mylogger import get_logger, parse_json
27
28sys.path.append(os.path.join(os.getcwd(), "mylogger.py"))
29Log = get_logger("build_gn")
30log_info = Log.info
31log_error = Log.error
32
33config = parse_json().get("gn_template")
34if not config:
35    log_error("config file: build_example.json error")
36    sys.exit(0)
37
38CURRENT_OHOS_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
39BUILD_SH_PATH = os.path.join(CURRENT_OHOS_ROOT, 'build.sh')
40
41TEMPLATE_SOURCE_PATH = config.get("template_source_path")
42RESULT_BUILT_FILE = config.get("result_build_file")
43BUILD_RES_PATH = CURRENT_OHOS_ROOT + RESULT_BUILT_FILE
44RESULT_OBJ_FILE = config.get("result_obj_file")
45RESULT_PATH = CURRENT_OHOS_ROOT + RESULT_OBJ_FILE
46RUST_PATH = config.get("rust_path")
47RESULT_RUST_FILE = config.get("result_rust_file")
48RUST_RESULT_IDL_PATH = CURRENT_OHOS_ROOT + RESULT_RUST_FILE
49EXCLUDE_LIST = config.get("exclude")
50TEST_BUILD = config.get("test_build")
51CONFIG_PATH = CURRENT_OHOS_ROOT + TEST_BUILD
52TIME_OUT = config.get("time_out")
53
54
55def remove_dir():
56    """
57    Description: this function is used to delete files in the out folder other than reports
58    """
59    out_dir = os.path.join(CURRENT_OHOS_ROOT, "out")
60    try:
61        if not os.path.exists(out_dir):
62            return
63        for tmp_dir in os.listdir(out_dir):
64            if tmp_dir in EXCLUDE_LIST:
65                continue
66            if os.path.isdir(os.path.join(out_dir, tmp_dir)):
67                shutil.rmtree(os.path.join(out_dir, tmp_dir))
68            else:
69                os.remove(os.path.join(out_dir, tmp_dir))
70    except Exception as e:
71        log_error(e)
72
73
74remove_dir()
75
76
77@pytest.fixture()
78def init_build_env():
79    def find_top_dir():
80        cur_dir = os.getcwd()
81        while cur_dir != "/":
82            build_scripts = os.path.join(
83                cur_dir, 'build/scripts/build_package_list.json')
84            if os.path.exists(build_scripts):
85                return cur_dir
86            cur_dir = os.path.dirname(cur_dir)
87
88    os.chdir(find_top_dir())
89    subprocess.run(['repo', 'forall', '-c', 'git reset --hard'],
90                   stdout=subprocess.PIPE, stderr=subprocess.PIPE)
91    subprocess.run(['repo', 'forall', '-c', 'git clean -dfx'],
92                   stdout=subprocess.PIPE, stderr=subprocess.PIPE)
93
94
95def exec_command_communicate(cmd_path, res_path, res_def_name, rust=None):
96    """
97    Description : execute the cmd command to return the terminal output value
98    @param cmd_path: the source code path for running commands
99    @param res_path: the generated product path
100    @param res_def_name: function name
101    @param rust: judgment flags for running test cases
102    @return True or False
103    """
104    if not rust == "rust":
105        write_bundle_json(res_def_name, cmd_path)
106    cmd = [BUILD_SH_PATH, '--product-name', 'rk3568', '--build-target', cmd_path]
107    try:
108        proc = subprocess.Popen(
109            cmd,
110            stdout=subprocess.PIPE,
111            stderr=subprocess.PIPE,
112            encoding="utf-8",
113            universal_newlines=True,
114            cwd=CURRENT_OHOS_ROOT
115        )
116        out, error = proc.communicate(timeout=TIME_OUT)
117        out_res = out.splitlines() + error.splitlines()
118        log_info(f"*******************returncode:{proc.returncode}*********************")
119        if proc.returncode == 0:
120            for row, data in enumerate(out_res):
121                log_info("【{}】:{}".format(row, data))
122            if os.path.exists(res_path):
123                log_info('*****************test succeed************************')
124                return True
125            else:
126                log_info(f"{res_def_name} is not exist")
127                return False
128        else:
129            for row, data in enumerate(out_res):
130                log_error("【{}】:{}".format(row, data))
131            return False
132    except Exception as e:
133        log_error("command execution failed: {}".format(e))
134        raise Exception("command execution failed: {}".format(e))
135
136
137def exec_command_out_put(cmd_path, res_def_name, error_log):
138    """
139    Description: execute the cmd command to return the terminal output value
140    @param cmd_path: the source code path for running commands
141    @param res_def_name: function name
142    @param error_log: use case judgment flag
143    @return True or False
144    """
145
146    write_bundle_json(res_def_name, cmd_path)
147    cmd = [BUILD_SH_PATH, '--product-name', 'rk3568', '--build-target', cmd_path]
148    try:
149        proc = subprocess.Popen(
150            cmd,
151            stdout=subprocess.PIPE,
152            stderr=subprocess.PIPE,
153            encoding="utf-8",
154            universal_newlines=True,
155            cwd=CURRENT_OHOS_ROOT
156        )
157        out, error = proc.communicate(timeout=TIME_OUT)
158        out_res = out.splitlines() + error.splitlines()
159        log_info(f"*******************returncode:{proc.returncode}*********************")
160        if proc.returncode != 0:
161            for row, data in enumerate(out_res):
162                log_info("【{}】:{}".format(row, data))
163            if error_log in out_res:
164                log_info('*****************test succeed************************')
165                return True
166            else:
167                log_info(f"{res_def_name} failed")
168                return False
169        else:
170            for row, data in enumerate(out_res):
171                log_error("【{}】:{}".format(row, data))
172            return False
173    except Exception as e:
174        log_error("command execution failed: {}".format(e))
175        raise Exception("command execution failed: {}".format(e))
176
177
178def exec_command_install_dir(cmd_path, res_def_name):
179    """
180    Description: execute the cmd command to return the terminal output value
181    @param cmd_path: the source code path for running commands
182    @param res_def_name: function name
183    @return True or False
184    """
185    write_bundle_json(res_def_name, cmd_path)
186    cmd = [BUILD_SH_PATH, '--product-name', 'rk3568', '--build-target', cmd_path]
187    try:
188        proc = subprocess.Popen(
189            cmd,
190            stdout=subprocess.PIPE,
191            stderr=subprocess.PIPE,
192            encoding="utf-8",
193            universal_newlines=True,
194            cwd=CURRENT_OHOS_ROOT
195        )
196        out, error = proc.communicate(timeout=TIME_OUT)
197        out_res = out.splitlines() + error.splitlines()
198        log_info(f"*******************returncode:{proc.returncode}*********************")
199        if proc.returncode == 0:
200            for row, data in enumerate(out_res):
201                log_info("【{}】:{}".format(row, data))
202            config_path = RESULT_PATH + res_def_name + "/{}_module_info.json".format(res_def_name)
203            with open(config_path, "r", encoding="utf-8") as json_file:
204                data = json.load(json_file)
205                res = str((data.get("dest"))[0])
206                module_install_dir = res_def_name
207            if module_install_dir in res:
208                log_info('*****************test succeed************************')
209                return True
210            else:
211                log_info(f"{res_def_name} is not exist")
212                return False
213        else:
214            for row, data in enumerate(out_res):
215                log_error("【{}】:{}".format(row, data))
216            return False
217    except Exception as e:
218        log_error("command execution failed: {}".format(e))
219        raise Exception("command execution failed: {}".format(e))
220
221
222def write_bundle_json(res_def_name, cmd_path):
223    """
224    Description: write bundle.json
225    @param res_def_name: function name
226    @param cmd_path: the source code path for running commands
227    """
228    with open(CONFIG_PATH, "r", encoding="utf-8") as json_file:
229        data = json.load(json_file)
230        res = data.get("component").get("build").get("sub_component")
231        res.append("//{}:{}".format(cmd_path, res_def_name))
232        data["component"]["build"]["sub_component"] = res
233    config_res = CURRENT_OHOS_ROOT + "/build/common/bundle.json"
234    with open(config_res, "w", encoding="utf-8") as json_file:
235        json.dump(data, json_file, indent=4, ensure_ascii=False)
236
237
238class TestModuleBuild:
239
240    def test_ohos_shared_library_output_dir(self):
241        """
242        test output dir
243        """
244        res_def_name = inspect.currentframe().f_code.co_name
245        error_log = "[OHOS INFO] output_dir is not allowed to be defined."
246        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
247        result = exec_command_out_put(cmd_path, res_def_name, error_log)
248        assert result, "build test_ohos_shared_library_output_dir failed"
249
250    def test_ohos_shared_library_testonly(self):
251        """
252        test testonly
253        """
254        error_log = "[OHOS INFO] ERROR at //build/ohos/ohos_part.gni:54:3: Test-only dependency not allowed."
255        res_def_name = inspect.currentframe().f_code.co_name
256        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
257        result = exec_command_out_put(cmd_path, res_def_name, error_log)
258        assert result, "build test_ohos_shared_library_testonly failed"
259
260    def test_ohos_shared_library(self):
261        """
262        test shared library
263        """
264        res_def_name = inspect.currentframe().f_code.co_name
265        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
266        res_path = BUILD_RES_PATH + "/libtest_ohos_shared_library.z.so"
267        result = exec_command_communicate(cmd_path, res_path, res_def_name)
268        assert result, "build test_ohos_shared_library failed"
269
270    def test_ohos_shared_library_output_name(self):
271        """
272        test output name
273        """
274        res_def_name = inspect.currentframe().f_code.co_name
275        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
276        res_path = BUILD_RES_PATH + "lib{}.{}".format(res_def_name, res_def_name)
277        result = exec_command_communicate(cmd_path, res_path, res_def_name)
278        assert result, " ohos_shared_library  template output_name and output_extension invalid"
279
280    def test_ohos_shared_library_output_extension(self):
281        """
282        test extension
283        """
284        res_def_name = "test_ohos_shared_library_output_name"
285        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
286        res_path = BUILD_RES_PATH + "lib{}.{}".format(res_def_name, res_def_name)
287        result = exec_command_communicate(cmd_path, res_path, res_def_name)
288        assert result, " ohos_shared_library  template output_name and output_extension invalid"
289
290    def test_ohos_shared_library_module_install_dir(self):
291        """
292        test module install dir
293        """
294        res_def_name = inspect.currentframe().f_code.co_name
295        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
296        result = exec_command_install_dir(cmd_path, res_def_name)
297        assert result, " test_ohos_shared_library_module_install_dir fail"
298
299    def test_ohos_shared_library_relative_install_dir(self):
300        """
301        test relative install dir
302        """
303        res_def_name = inspect.currentframe().f_code.co_name
304        cmd_path = TEMPLATE_SOURCE_PATH + res_def_name
305        result = exec_command_install_dir(cmd_path, res_def_name)
306        assert result, " test_ohos_shared_library_relative_install_dir fail"
307
308    def test_ohos_static_library(self):
309        """
310        test static library
311        """
312        function_name = inspect.currentframe().f_code.co_name
313        cmd_path = TEMPLATE_SOURCE_PATH + function_name
314        res_path = RESULT_PATH + "/src/" + function_name + "/hello.o"
315        result = exec_command_communicate(cmd_path, res_path, function_name)
316        assert result, "build test_ohos_static_library failed"
317
318    def test_ohos_source_set(self):
319        """
320        test source set
321        """
322        function_name = inspect.currentframe().f_code.co_name
323        cmd_path = TEMPLATE_SOURCE_PATH + function_name
324        res_path = RESULT_PATH + "/src/" + function_name + "/adder.o"
325        result = exec_command_communicate(cmd_path, res_path, function_name)
326        assert result, "build test_ohos_source_set failed"
327
328    def test_ohos_executable(self):
329        """
330        test ohos executable
331        """
332        function_name = inspect.currentframe().f_code.co_name
333        common_res_def = TEMPLATE_SOURCE_PATH + function_name
334        res_path = BUILD_RES_PATH + function_name
335        result = exec_command_communicate(common_res_def, res_path, function_name)
336        assert result, "build test_ohos_executable failed"
337
338
339class TestPrecompiledBuild:
340
341    def test_ohos_prebuilt_executable(self):
342        """
343        test prebuilt executable
344        """
345        function_name = inspect.currentframe().f_code.co_name
346        cmd_common = TEMPLATE_SOURCE_PATH + function_name
347        res_path = RESULT_PATH + function_name + "/test_ohos_prebuilt_executable.stamp"
348        result = exec_command_communicate(cmd_common, res_path, function_name)
349        assert result, "build test_ohos_prebuilt_executable failed"
350
351    def test_ohos_prebuilt_shared_library(self):
352        """
353        test _prebuilt shared library
354        """
355        function_name = inspect.currentframe().f_code.co_name
356        common_res_def = TEMPLATE_SOURCE_PATH + function_name
357        res_path = RESULT_PATH + function_name + "/test_ohos_prebuilt_shared_library.stamp"
358        result = exec_command_communicate(common_res_def, res_path, function_name)
359        assert result, "build test_ohos_prebuilt_shared_library failed"
360
361    def test_ohos_prebuilt_static_library(self):
362        """
363        test prebuilt static library
364        """
365        function_name = inspect.currentframe().f_code.co_name
366        common_res_def = TEMPLATE_SOURCE_PATH + function_name
367        res_path = RESULT_PATH + function_name + "/test_ohos_prebuilt_static_library.stamp"
368        result = exec_command_communicate(common_res_def, res_path, function_name)
369        assert result, "build test_ohos_prebuilt_static_library failed"
370
371
372class TestOtherPrebuilt:
373
374    def test_ohos_sa_profile(self):
375        """
376        test ohos_sa_profile
377        """
378        function_name = inspect.currentframe().f_code.co_name
379        cmd_path = TEMPLATE_SOURCE_PATH + function_name
380        profile_result_path = RESULT_PATH + function_name
381        result = exec_command_communicate(cmd_path, profile_result_path, function_name)
382        assert result, "build test_ohos_sa_profile failed"
383
384    def test_ohos_prebuilt_etc(self):
385        """
386        test ohos_prebuilt_etc
387        """
388        function_name = inspect.currentframe().f_code.co_name
389        cmd_path = TEMPLATE_SOURCE_PATH + function_name
390        rebuilt_result_path = RESULT_PATH + function_name
391        result = exec_command_communicate(cmd_path, rebuilt_result_path, function_name)
392        assert result, "build test_ohos_prebuilt_etc failed"
393
394
395class TestRustBuild:
396
397    def test_bin_cargo_crate(self):
398        """
399        test bin_cargo_crate
400        """
401        function_name = inspect.currentframe().f_code.co_name
402        cmd_path = RUST_PATH + function_name
403        res_path = os.path.join(BUILD_RES_PATH, function_name)
404        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
405        assert result, "build test_bin_cargo_crate failed"
406
407    def test_bin_crate(self):
408        """
409        test bin_crate
410        """
411        function_name = inspect.currentframe().f_code.co_name
412        cmd_path = RUST_PATH + function_name
413        res_path = os.path.join(BUILD_RES_PATH, function_name)
414        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
415        assert result, "build test_bin_crate failed"
416
417    def test_extern_c(self):
418        """
419        test extern_c
420        """
421        function_name = inspect.currentframe().f_code.co_name
422        cmd_path = RUST_PATH + "test_bindgen_test/test_for_extern_c:test_extern_c"
423        res_path = os.path.join(BUILD_RES_PATH, function_name)
424        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
425        assert result, "build test_extern_c failed"
426
427    def test_for_h(self):
428        """
429        test for_h
430        """
431        function_name = inspect.currentframe().f_code.co_name
432        cmd_path = RUST_PATH + "test_bindgen_test/test_for_h:bindgen_test_for_h"
433        res_path = os.path.join(BUILD_RES_PATH, 'bindgen_test_for_h')
434        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
435        assert result, "build bindgen_test_for_h failed"
436
437    def test_for_hello_world(self):
438        """
439        test for_hello_world
440        """
441        function_name = inspect.currentframe().f_code.co_name
442        cmd_path = RUST_PATH + "test_bindgen_test/test_for_hello_world:bindgen_test"
443        res_path = os.path.join(BUILD_RES_PATH, 'bindgen_test')
444        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
445        assert result, "build test_for_hello_world failed"
446
447    def test_for_hpp(self):
448        """
449        test for_hpp
450        """
451        function_name = inspect.currentframe().f_code.co_name
452        cmd_path = RUST_PATH + "test_bindgen_test/test_for_hpp:bindgen_test_hpp"
453        res_path = os.path.join(BUILD_RES_PATH, 'bindgen_test_hpp')
454        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
455        assert result, "build bindgen_test_hpp failed"
456
457    def test_cdylib_crate(self):
458        """
459        test cdylib_crate
460        """
461        function_name = inspect.currentframe().f_code.co_name
462        cmd_path = RUST_PATH + function_name
463        res_path = os.path.join(BUILD_RES_PATH, function_name)
464        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
465        assert result, "build test_cdylib_crate failed"
466
467    def test_cxx_exe(self):
468        """
469        test cxx_exe
470        """
471        function_name = inspect.currentframe().f_code.co_name
472        cmd_path = RUST_PATH + "test_cxx" + ":" + function_name
473        res_path = os.path.join(BUILD_RES_PATH, function_name)
474        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
475        assert result, "build test_cxx_exe failed"
476
477    def test_cxx_rust(self):
478        """
479        test cxx_rust
480        """
481        function_name = inspect.currentframe().f_code.co_name
482        cmd_path = RUST_PATH + function_name
483        res_path = os.path.join(BUILD_RES_PATH, function_name)
484        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
485
486        assert result, "build test_cxx_rust failed"
487
488    def test_dylib_crate(self):
489        """
490        test dylib_crate
491        """
492        function_name = inspect.currentframe().f_code.co_name
493        cmd_path = RUST_PATH + function_name
494        res_path = os.path.join(BUILD_RES_PATH, function_name)
495        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
496        assert result, "build test_cxx_rust failed"
497
498    def test_idl(self):
499        """
500        test test_idl
501        """
502        function_name = inspect.currentframe().f_code.co_name
503        cmd_path = RUST_PATH + "test_idl"
504        res_path = os.path.join(RUST_RESULT_IDL_PATH, function_name, 'test_idl.stamp')
505        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
506        assert result, "build test_idl failed"
507
508    def test_rlib_cargo_crate(self):
509        """
510        test rlib_cargo_crate
511        """
512        function_name = inspect.currentframe().f_code.co_name
513        cmd_path = RUST_PATH + function_name + ':' + 'test_rlib_crate_associated_bin'
514        res_path = os.path.join(BUILD_RES_PATH, 'test_rlib_crate_associated_bin')
515        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
516        assert result, "build test_rlib_cargo_crate failed"
517
518    def test_rlib_crate(self):
519        """
520        test rlib_crate
521        """
522        function_name = inspect.currentframe().f_code.co_name
523        cmd_path = RUST_PATH + function_name
524        res_path = os.path.join(BUILD_RES_PATH, function_name)
525        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
526        assert result, "build test_rlib_crate failed"
527
528    def test_rust_st(self):
529        """
530        test rust_st
531        """
532        function_name = inspect.currentframe().f_code.co_name
533        cmd_path = RUST_PATH + function_name
534        res_path = os.path.join(BUILD_RES_PATH, 'libtest_rust_st_add.dylib.so')
535        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
536        assert result, "build test_rust_st failed"
537
538    def test_rust_ut(self):
539        """
540        test rust_ut
541        """
542        function_name = inspect.currentframe().f_code.co_name
543        cmd_path = RUST_PATH + function_name
544        res_path = os.path.join(BUILD_RES_PATH, 'libtest_rust_ut_add.dylib.so')
545        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
546        assert result, "build test_rust_ut failed"
547
548    def test_static_link(self):
549        """
550        test static_link
551        """
552        function_name = inspect.currentframe().f_code.co_name
553        cmd_path = RUST_PATH + function_name
554        res_path = os.path.join(BUILD_RES_PATH, function_name)
555        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
556        assert result, "build test_static_link failed"
557
558    def test_staticlib_crate(self):
559        """
560        test staticlib_crate
561        """
562        function_name = inspect.currentframe().f_code.co_name
563        cmd_path = RUST_PATH + function_name
564        res_path = os.path.join(BUILD_RES_PATH, function_name)
565        result = exec_command_communicate(cmd_path, res_path, function_name, rust='rust')
566        assert result, "build test_staticlib_crate failed"
567
568
569def write_initial_bundle_json():
570    """
571    Description: write initial bundle.json
572    """
573    with open(CONFIG_PATH, "r", encoding="utf-8") as json_file:
574        data = json.load(json_file)
575    config_res = CURRENT_OHOS_ROOT + "/build/common/bundle.json"
576    with open(config_res, "w", encoding="utf-8") as json_file:
577        json.dump(data, json_file, indent=4, ensure_ascii=False)
578
579
580write_initial_bundle_json()
581
582