123b3eb3cSopenharmony_ci#!/usr/bin/env python3 223b3eb3cSopenharmony_ci# -*- coding: utf-8 -*- 323b3eb3cSopenharmony_ci 423b3eb3cSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 523b3eb3cSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 623b3eb3cSopenharmony_ci# you may not use this file except in compliance with the License. 723b3eb3cSopenharmony_ci# You may obtain a copy of the License at 823b3eb3cSopenharmony_ci# 923b3eb3cSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 1023b3eb3cSopenharmony_ci# 1123b3eb3cSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1223b3eb3cSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1323b3eb3cSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1423b3eb3cSopenharmony_ci# See the License for the specific language governing permissions and 1523b3eb3cSopenharmony_ci# limitations under the License. 1623b3eb3cSopenharmony_ci 1723b3eb3cSopenharmony_ciimport os 1823b3eb3cSopenharmony_ciimport time 1923b3eb3cSopenharmony_ciimport json 2023b3eb3cSopenharmony_ciimport stat 2123b3eb3cSopenharmony_ciimport argparse 2223b3eb3cSopenharmony_ciimport subprocess 2323b3eb3cSopenharmony_ciimport multiprocessing 2423b3eb3cSopenharmony_ciimport xml.etree.ElementTree as ET 2523b3eb3cSopenharmony_cifrom datetime import datetime 2623b3eb3cSopenharmony_ci 2723b3eb3cSopenharmony_ci 2823b3eb3cSopenharmony_cidef parse_xml(xml_file_path): 2923b3eb3cSopenharmony_ci """ 3023b3eb3cSopenharmony_ci Parse the XML file of the execution output of the use case 3123b3eb3cSopenharmony_ci """ 3223b3eb3cSopenharmony_ci tree = ET.parse(xml_file_path) 3323b3eb3cSopenharmony_ci root = tree.getroot() 3423b3eb3cSopenharmony_ci tests = root.attrib.get("tests") 3523b3eb3cSopenharmony_ci failures = root.attrib.get("failures") 3623b3eb3cSopenharmony_ci failed_info = { 3723b3eb3cSopenharmony_ci "test_suite_name": [], 3823b3eb3cSopenharmony_ci "total_count": tests, 3923b3eb3cSopenharmony_ci "failed_count": failures, 4023b3eb3cSopenharmony_ci "failed_testcase_name": [] 4123b3eb3cSopenharmony_ci } 4223b3eb3cSopenharmony_ci for testsuite in root.findall(".//testsuite"): 4323b3eb3cSopenharmony_ci testsuite_name = testsuite.attrib.get("name") 4423b3eb3cSopenharmony_ci testsuite_failures = testsuite.attrib.get("failures") 4523b3eb3cSopenharmony_ci if int(testsuite_failures): 4623b3eb3cSopenharmony_ci failed_info["test_suite_name"].append(testsuite_name) 4723b3eb3cSopenharmony_ci for testcase in testsuite.findall(".//testcase"): 4823b3eb3cSopenharmony_ci testcase_name = testcase.attrib.get("name") 4923b3eb3cSopenharmony_ci failure = testcase.find("failure") 5023b3eb3cSopenharmony_ci if failure is not None: 5123b3eb3cSopenharmony_ci failed_info["failed_testcase_name"].append(testcase_name) 5223b3eb3cSopenharmony_ci return failed_info 5323b3eb3cSopenharmony_ci 5423b3eb3cSopenharmony_ci 5523b3eb3cSopenharmony_cidef run_command(test_binary_path: str, alter_cmds: list = None): 5623b3eb3cSopenharmony_ci """ 5723b3eb3cSopenharmony_ci Run a gtest test binary. 5823b3eb3cSopenharmony_ci """ 5923b3eb3cSopenharmony_ci default_cmds = [] 6023b3eb3cSopenharmony_ci default_cmds.append(test_binary_path) 6123b3eb3cSopenharmony_ci default_cmds.append("--gtest_output=xml:{}.xml".format(test_binary_path)) 6223b3eb3cSopenharmony_ci default_cmds.append("--gtest_print_time=0") 6323b3eb3cSopenharmony_ci default_cmds.append("--gtest_brief=1") 6423b3eb3cSopenharmony_ci if alter_cmds is not None: 6523b3eb3cSopenharmony_ci default_cmds.extend(alter_cmds) 6623b3eb3cSopenharmony_ci subprocess.run(default_cmds) 6723b3eb3cSopenharmony_ci 6823b3eb3cSopenharmony_ci 6923b3eb3cSopenharmony_cidef run_single_test(tests_path, test_suite_name): 7023b3eb3cSopenharmony_ci """ 7123b3eb3cSopenharmony_ci Run a gtest test suite 7223b3eb3cSopenharmony_ci """ 7323b3eb3cSopenharmony_ci test_suite_path = None 7423b3eb3cSopenharmony_ci for root, _, files in os.walk(tests_path): 7523b3eb3cSopenharmony_ci for file in files: 7623b3eb3cSopenharmony_ci if file.endswith(test_suite_name): 7723b3eb3cSopenharmony_ci test_suite_path = os.path.join(root, test_suite_name) 7823b3eb3cSopenharmony_ci if test_suite_path is not None: 7923b3eb3cSopenharmony_ci run_command(test_suite_path) 8023b3eb3cSopenharmony_ci else: 8123b3eb3cSopenharmony_ci print("TestSuite {} did not compile successfully.".format(test_suite_name)) 8223b3eb3cSopenharmony_ci 8323b3eb3cSopenharmony_ci 8423b3eb3cSopenharmony_cidef run_tests_parallel(test_directory): 8523b3eb3cSopenharmony_ci """ 8623b3eb3cSopenharmony_ci Run all gtest test binaries in parallel. 8723b3eb3cSopenharmony_ci """ 8823b3eb3cSopenharmony_ci test_binaries = [] 8923b3eb3cSopenharmony_ci for root, _, files in os.walk(test_directory): 9023b3eb3cSopenharmony_ci for file in files: 9123b3eb3cSopenharmony_ci test_suite_path = os.path.join(root, file) 9223b3eb3cSopenharmony_ci name, ext = os.path.splitext(file) 9323b3eb3cSopenharmony_ci if ext == "": 9423b3eb3cSopenharmony_ci test_binaries.append(test_suite_path) 9523b3eb3cSopenharmony_ci start = time.time() 9623b3eb3cSopenharmony_ci with multiprocessing.Pool(processes=64) as pool: 9723b3eb3cSopenharmony_ci pool.map(run_command, iter(test_binaries)) 9823b3eb3cSopenharmony_ci end = time.time() 9923b3eb3cSopenharmony_ci test_result = { 10023b3eb3cSopenharmony_ci "time_stamp": str(datetime.now()), 10123b3eb3cSopenharmony_ci "execute_time": 0, 10223b3eb3cSopenharmony_ci "total_execute_tests": 0, 10323b3eb3cSopenharmony_ci "failed_tests_count": 0, 10423b3eb3cSopenharmony_ci "unavailable": [], 10523b3eb3cSopenharmony_ci "failed": [] 10623b3eb3cSopenharmony_ci } 10723b3eb3cSopenharmony_ci total_tests_count = 0 10823b3eb3cSopenharmony_ci failed_tests_count = 0 10923b3eb3cSopenharmony_ci for test_binary in test_binaries: 11023b3eb3cSopenharmony_ci xml_file_path = "{}.xml".format(test_binary) 11123b3eb3cSopenharmony_ci if os.path.exists(xml_file_path): 11223b3eb3cSopenharmony_ci failed_info = parse_xml(xml_file_path) 11323b3eb3cSopenharmony_ci total_tests_count = total_tests_count + int(failed_info.get('total_count', '0')) 11423b3eb3cSopenharmony_ci failed_tests_count = failed_tests_count + int(failed_info.get('failed_count', '0')) 11523b3eb3cSopenharmony_ci if int(failed_info.get('failed_count', '0')): 11623b3eb3cSopenharmony_ci test_result['failed'].append(failed_info) 11723b3eb3cSopenharmony_ci else: 11823b3eb3cSopenharmony_ci test_result["unavailable"].append(test_binary.split('/')[-1]) 11923b3eb3cSopenharmony_ci test_result["execute_time"] = "{} seconds".format(round(end - start, 2)) 12023b3eb3cSopenharmony_ci test_result['total_execute_tests'] = total_tests_count 12123b3eb3cSopenharmony_ci test_result['failed_tests_count'] = failed_tests_count 12223b3eb3cSopenharmony_ci json_file_path = os.path.join(test_directory, "test_result.json") 12323b3eb3cSopenharmony_ci flags = os.O_CREAT | os.O_WRONLY | os.O_TRUNC 12423b3eb3cSopenharmony_ci mode = stat.S_IRUSR | stat.S_IWUSR 12523b3eb3cSopenharmony_ci with os.fdopen(os.open(json_file_path, flags, mode), 'w') as json_file: 12623b3eb3cSopenharmony_ci json.dump(test_result, json_file, indent=2) 12723b3eb3cSopenharmony_ci 12823b3eb3cSopenharmony_ci print("The test results have been generated, path is {}".format(json_file_path)) 12923b3eb3cSopenharmony_ci 13023b3eb3cSopenharmony_ci 13123b3eb3cSopenharmony_cidef get_tests_out_path(): 13223b3eb3cSopenharmony_ci """ 13323b3eb3cSopenharmony_ci Obtain the output directory of test cases 13423b3eb3cSopenharmony_ci """ 13523b3eb3cSopenharmony_ci code_path = os.getcwd() 13623b3eb3cSopenharmony_ci for _ in range(6): 13723b3eb3cSopenharmony_ci code_path = os.path.dirname(code_path) 13823b3eb3cSopenharmony_ci code_path = os.path.join(code_path, "out/rk3568/clang_x64/tests/unittest/ace_engine") 13923b3eb3cSopenharmony_ci return code_path 14023b3eb3cSopenharmony_ci 14123b3eb3cSopenharmony_ci 14223b3eb3cSopenharmony_cidef main(): 14323b3eb3cSopenharmony_ci """ 14423b3eb3cSopenharmony_ci Add unitest case execution parameters 14523b3eb3cSopenharmony_ci """ 14623b3eb3cSopenharmony_ci parser = argparse.ArgumentParser() 14723b3eb3cSopenharmony_ci parser.add_argument("-t", "--target", nargs='+', type=str, default=None) 14823b3eb3cSopenharmony_ci tests_out_path = get_tests_out_path() 14923b3eb3cSopenharmony_ci args = parser.parse_args() 15023b3eb3cSopenharmony_ci targets = args.target 15123b3eb3cSopenharmony_ci if targets is not None: 15223b3eb3cSopenharmony_ci for target in targets: 15323b3eb3cSopenharmony_ci run_single_test(tests_out_path, target) 15423b3eb3cSopenharmony_ci else: 15523b3eb3cSopenharmony_ci run_tests_parallel(tests_out_path) 15623b3eb3cSopenharmony_ci 15723b3eb3cSopenharmony_ci 15823b3eb3cSopenharmony_ciif __name__ == "__main__": 15923b3eb3cSopenharmony_ci main() 160