13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# -*- coding: utf-8 -*-
33af6ab5fSopenharmony_ci
43af6ab5fSopenharmony_ci# Copyright (c) 2022-2024 Huawei Device Co., Ltd.
53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
73af6ab5fSopenharmony_ci# You may obtain a copy of the License at
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
103af6ab5fSopenharmony_ci#
113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
153af6ab5fSopenharmony_ci# limitations under the License.
163af6ab5fSopenharmony_ci
173af6ab5fSopenharmony_ciimport re
183af6ab5fSopenharmony_ciimport argparse
193af6ab5fSopenharmony_ciimport subprocess
203af6ab5fSopenharmony_ciimport time
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_cifrom enum import Enum
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_ciclass TestTypes(Enum):
263af6ab5fSopenharmony_ci    NORMAL = 0
273af6ab5fSopenharmony_ci    CLANGTIDY = 1
283af6ab5fSopenharmony_ci    CLANGFORMAT = 2
293af6ab5fSopenharmony_ci
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_cidef print_summary(log_lines, searched_words, end_word=""):
323af6ab5fSopenharmony_ci    was_any_log = False
333af6ab5fSopenharmony_ci    should_print = False
343af6ab5fSopenharmony_ci
353af6ab5fSopenharmony_ci    for line in log_lines:
363af6ab5fSopenharmony_ci        for word in searched_words:
373af6ab5fSopenharmony_ci            if any(word in line for word in searched_words):
383af6ab5fSopenharmony_ci                should_print = True
393af6ab5fSopenharmony_ci                was_any_log = True
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_ci        if end_word and end_word in line:
423af6ab5fSopenharmony_ci            should_print=False
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ci        if should_print:
453af6ab5fSopenharmony_ci            print(line.strip())
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ci    if not was_any_log:
483af6ab5fSopenharmony_ci        print("Problem occourd: ", was_any_log)
493af6ab5fSopenharmony_ci
503af6ab5fSopenharmony_ci    print(f"\n")
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci
533af6ab5fSopenharmony_cidef print_progress_to_console(line, test_type, pattern_progress_bar, pattern_clang_tidy, pattern_clang_format):
543af6ab5fSopenharmony_ci    match test_type:
553af6ab5fSopenharmony_ci        case TestTypes.NORMAL:
563af6ab5fSopenharmony_ci            match = pattern_progress_bar.search(line)
573af6ab5fSopenharmony_ci            if match:
583af6ab5fSopenharmony_ci                print(line, end='')
593af6ab5fSopenharmony_ci        case TestTypes.CLANGTIDY:
603af6ab5fSopenharmony_ci            match = re.match(pattern_clang_tidy, line)
613af6ab5fSopenharmony_ci            if match:
623af6ab5fSopenharmony_ci                print(f"[{match.group(1)}/{match.group(2)}] {match.group(3)}")
633af6ab5fSopenharmony_ci        case TestTypes.CLANGFORMAT:
643af6ab5fSopenharmony_ci            match = re.match(pattern_clang_format, line)
653af6ab5fSopenharmony_ci            if match:
663af6ab5fSopenharmony_ci                print(f"[{match.group(1)}/{match.group(2)}] Clang-format: {match.group(3)} \n")
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ci
693af6ab5fSopenharmony_cidef test_process_runner(runtime_process, test_type):
703af6ab5fSopenharmony_ci    pattern_progress_bar = re.compile(r'\b(\d{1,3}%)\|(.+?)\| (\d+)/(\d+) \[\d{2}:\d{2}<\d{2}:\d{2},\s*\d+\.\d+it/s\]$')
713af6ab5fSopenharmony_ci    pattern_clang_tidy = re.compile(r"^\[(\d+)\/(\d+)\]\s+Done\s+clang-tidy:\s+.*?\/es2panda\/(.+\.cpp)$")
723af6ab5fSopenharmony_ci    pattern_clang_format = re.compile(r"\[(\d+)/(\d+)\]\s+Running clang-format: (.+)")
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci    should_print = False
753af6ab5fSopenharmony_ci    log_lines = []
763af6ab5fSopenharmony_ci
773af6ab5fSopenharmony_ci    for line in runtime_process.stdout:
783af6ab5fSopenharmony_ci        log_lines.append(line)
793af6ab5fSopenharmony_ci        print_progress_to_console(line, test_type, pattern_progress_bar, pattern_clang_tidy, pattern_clang_format)
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci    return log_lines
823af6ab5fSopenharmony_ci
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_cidef command_runner(command_to_run, test_type):
853af6ab5fSopenharmony_ci    try:
863af6ab5fSopenharmony_ci        process = subprocess.Popen(command_to_run, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
873af6ab5fSopenharmony_ci        process_log = test_process_runner(process, test_type)
883af6ab5fSopenharmony_ci
893af6ab5fSopenharmony_ci    except subprocess.CalledProcessError as e:
903af6ab5fSopenharmony_ci        process_log = str(e)
913af6ab5fSopenharmony_ci        print("An error occurred during processing:", process_log)
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci    except Exception as e:
943af6ab5fSopenharmony_ci        process_log = str(e)
953af6ab5fSopenharmony_ci        print("An error occurred during processing:", process_log)
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci    return process_log
983af6ab5fSopenharmony_ci
993af6ab5fSopenharmony_cidef print_summary_to_file(log, file_name, word_for_success, word_for_fail, test_name):
1003af6ab5fSopenharmony_ci    has_to_write_out_the_log = False
1013af6ab5fSopenharmony_ci
1023af6ab5fSopenharmony_ci    for line in log:
1033af6ab5fSopenharmony_ci        if word_for_fail in line:
1043af6ab5fSopenharmony_ci            has_to_write_out_the_log = True
1053af6ab5fSopenharmony_ci        elif word_for_success in line:
1063af6ab5fSopenharmony_ci            print(line)
1073af6ab5fSopenharmony_ci
1083af6ab5fSopenharmony_ci    if has_to_write_out_the_log:
1093af6ab5fSopenharmony_ci        with open(file_name, "w") as file:
1103af6ab5fSopenharmony_ci            for line in log:
1113af6ab5fSopenharmony_ci                file.write(line)
1123af6ab5fSopenharmony_ci
1133af6ab5fSopenharmony_ci        print(f"{test_name} is faild. Please check the log file: {file_name}")
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_cidef main():
1173af6ab5fSopenharmony_ci    parser = argparse.ArgumentParser(description="Program description.")
1183af6ab5fSopenharmony_ci    parser.add_argument("--working-dir", required=False, help="Path to the working dir")
1193af6ab5fSopenharmony_ci    parser.add_argument("--build-root", required=False, help="Path to the working dir")
1203af6ab5fSopenharmony_ci
1213af6ab5fSopenharmony_ci    args = parser.parse_args()
1223af6ab5fSopenharmony_ci    print(f"Argumentum: Working dir: {args.working_dir}")
1233af6ab5fSopenharmony_ci    print(f"Argumentum: Build root: {args.build_root}")
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci    command_helper = ["python3", f"{args.working_dir}/tests/tests-u-runner/main.py", "--build-dir", f"{args.build_root}",
1263af6ab5fSopenharmony_ci                      "--processes", "all", "--show-progress", "--force-generate"
1273af6ab5fSopenharmony_ci                    ]
1283af6ab5fSopenharmony_ci
1293af6ab5fSopenharmony_ci    # Run Parser tests
1303af6ab5fSopenharmony_ci    parser_test_run_command = command_helper + ["--parser" ]
1313af6ab5fSopenharmony_ci
1323af6ab5fSopenharmony_ci    parser_log = command_runner(parser_test_run_command, TestTypes.NORMAL)
1333af6ab5fSopenharmony_ci
1343af6ab5fSopenharmony_ci    # Run Runtime tests
1353af6ab5fSopenharmony_ci    runtime_test_run_command = command_helper + ["--ets-runtime", "--timeout", "60"]
1363af6ab5fSopenharmony_ci
1373af6ab5fSopenharmony_ci    runtime_log = command_runner(runtime_test_run_command, TestTypes.NORMAL)
1383af6ab5fSopenharmony_ci
1393af6ab5fSopenharmony_ci    # Functional tests
1403af6ab5fSopenharmony_ci    functional_test_run_command = command_helper + ["--ets-func-tests"]
1413af6ab5fSopenharmony_ci
1423af6ab5fSopenharmony_ci    functional_log = command_runner(functional_test_run_command, TestTypes.NORMAL)
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_ci    # Run Ets-cts test
1453af6ab5fSopenharmony_ci    ets_cts_test_run_command =  command_helper + ["--ets-cts"]
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci    ets_cts_log = command_runner(ets_cts_test_run_command, TestTypes.NORMAL)
1483af6ab5fSopenharmony_ci
1493af6ab5fSopenharmony_ci    # Run Clang-format
1503af6ab5fSopenharmony_ci    clang_format_run_command = ["ninja", "-C", f"{args.build_root}", "code-style-check"]
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_ci    clang_format_log = command_runner(clang_format_run_command, TestTypes.CLANGFORMAT)
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci    # Run Clang-tidy
1553af6ab5fSopenharmony_ci    clang_tidy_run_command = [f"{args.working_dir}/scripts/clang-tidy/clang_tidy_check.py", "--filename-filter=ets2panda",
1563af6ab5fSopenharmony_ci                                    f"{args.working_dir}",  f"{args.build_root}"
1573af6ab5fSopenharmony_ci                            ]
1583af6ab5fSopenharmony_ci
1593af6ab5fSopenharmony_ci    clang_tidy_log = command_runner(clang_tidy_run_command,TestTypes.CLANGTIDY)
1603af6ab5fSopenharmony_ci
1613af6ab5fSopenharmony_ci    print("\n\nTest results: \n")
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    print(f"\nParser test results:")
1643af6ab5fSopenharmony_ci    print_summary(parser_log, ["New failures at", "Summary("])
1653af6ab5fSopenharmony_ci
1663af6ab5fSopenharmony_ci    print(f"\nRuntime test results:")
1673af6ab5fSopenharmony_ci    print_summary(runtime_log, ["New failures at", "Summary("])
1683af6ab5fSopenharmony_ci
1693af6ab5fSopenharmony_ci    print(f"\nFunctional test results:")
1703af6ab5fSopenharmony_ci    print_summary(functional_log, ["Summary("])
1713af6ab5fSopenharmony_ci
1723af6ab5fSopenharmony_ci    print(f"\nEts-cts test results:")
1733af6ab5fSopenharmony_ci    print_summary(ets_cts_log, ["New failures at", "Summary("])
1743af6ab5fSopenharmony_ci
1753af6ab5fSopenharmony_ci    print(f"\nClang-format results:")
1763af6ab5fSopenharmony_ci    print_summary_to_file(clang_format_log, "clang-format.log", "Clang-format was passed successfully!", "Failed:", "Clang-format")
1773af6ab5fSopenharmony_ci
1783af6ab5fSopenharmony_ci    print(f"\nClang-tidy results:")
1793af6ab5fSopenharmony_ci    print_summary(clang_tidy_log,["Clang-tidy was passed successfully!", "Failed:"], "Done clang-tidy:")
1803af6ab5fSopenharmony_ci
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ciif __name__ == "__main__":
1833af6ab5fSopenharmony_ci    start_time = time.perf_counter()
1843af6ab5fSopenharmony_ci    main()
1853af6ab5fSopenharmony_ci    end_time = time.perf_counter()
1863af6ab5fSopenharmony_ci    print("Runtime: ", (end_time - start_time)/60, " minute" )
187