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