13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# -*- coding: utf-8 -*-
33af6ab5fSopenharmony_ci
43af6ab5fSopenharmony_ci"""
53af6ab5fSopenharmony_ciCopyright (c) 2023 Huawei Device Co., Ltd.
63af6ab5fSopenharmony_ciLicensed under the Apache License, Version 2.0 (the "License");
73af6ab5fSopenharmony_ciyou may not use this file except in compliance with the License.
83af6ab5fSopenharmony_ciYou may obtain a copy of the License at
93af6ab5fSopenharmony_ci
103af6ab5fSopenharmony_ci    http://www.apache.org/licenses/LICENSE-2.0
113af6ab5fSopenharmony_ci
123af6ab5fSopenharmony_ciUnless required by applicable law or agreed to in writing, software
133af6ab5fSopenharmony_cidistributed under the License is distributed on an "AS IS" BASIS,
143af6ab5fSopenharmony_ciWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
153af6ab5fSopenharmony_ciSee the License for the specific language governing permissions and
163af6ab5fSopenharmony_cilimitations under the License.
173af6ab5fSopenharmony_ci"""
183af6ab5fSopenharmony_ciimport os
193af6ab5fSopenharmony_ciimport shutil
203af6ab5fSopenharmony_ciimport subprocess
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_cifrom config import BUILD_HERMES_CMDS, HERMES_BUILD_LOG_PATH, HERMES_CLONE_PATH, REPORT_DIR, LOG_FILE, \
233af6ab5fSopenharmony_ci    CASE_URLS, CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, SUNSPIDER, KRAKEN, \
243af6ab5fSopenharmony_ci    CASE_LIST, KRAKENBENCHMARK_CASE_PATH, KRAKEN_CASE_PATH, SUNSPIDER_CASE_PATH, JS_FILE_SUFFIX, \
253af6ab5fSopenharmony_ci    CASE_DATA_SUFFIX, HTML_TEMPLATE, DEFAULT_TIME, AVERAGE_TIME, HTML_SCRIPT, SELECTED_PARAMETERS_BASE, \
263af6ab5fSopenharmony_ci    HTML_TABLE_DEFAULT, HTML_TABLE_COMP, HERMES_GIT_URL, ES2ABC, HERMES
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_cidef write_result(log_str):
303af6ab5fSopenharmony_ci    write_log_file(os.path.join(REPORT_DIR, LOG_FILE), log_str)
313af6ab5fSopenharmony_ci
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_cidef write_log_file(file_path, log_str):
343af6ab5fSopenharmony_ci    with open(file_path, mode='a+') as f:
353af6ab5fSopenharmony_ci        f.write(log_str)
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_cidef traverse_dir(path):
393af6ab5fSopenharmony_ci    file_paths = {}
403af6ab5fSopenharmony_ci    for file in os.listdir(path):
413af6ab5fSopenharmony_ci        file_path = os.path.join(path, file)
423af6ab5fSopenharmony_ci        if os.path.isdir(file_path):
433af6ab5fSopenharmony_ci            file_paths.update(traverse_dir(file_path))
443af6ab5fSopenharmony_ci        else:
453af6ab5fSopenharmony_ci            dir_name = os.path.dirname(file_path)
463af6ab5fSopenharmony_ci            if dir_name not in file_paths:
473af6ab5fSopenharmony_ci                file_paths[dir_name] = [file_path]
483af6ab5fSopenharmony_ci            else:
493af6ab5fSopenharmony_ci                file_paths[dir_name].append(file_path)
503af6ab5fSopenharmony_ci    return file_paths
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci
533af6ab5fSopenharmony_cidef run_cmd_cwd(cmds):
543af6ab5fSopenharmony_ci    p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
553af6ab5fSopenharmony_ci    p.wait()
563af6ab5fSopenharmony_ci    return p.returncode
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_cidef git_clone(git_url, code_dir):
603af6ab5fSopenharmony_ci    cmd = ['git', 'clone', git_url, code_dir]
613af6ab5fSopenharmony_ci    ret = run_cmd_cwd(cmd)
623af6ab5fSopenharmony_ci    result = True
633af6ab5fSopenharmony_ci    if ret:
643af6ab5fSopenharmony_ci        print(f"\n error: Cloning '{git_url}' failed.")
653af6ab5fSopenharmony_ci        result = False
663af6ab5fSopenharmony_ci    return result
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ci
693af6ab5fSopenharmony_cidef clear_folder_shutil(path):
703af6ab5fSopenharmony_ci    if os.path.exists(path):
713af6ab5fSopenharmony_ci        shutil.rmtree(path)
723af6ab5fSopenharmony_ci    os.mkdir(path)
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_cidef remove_dir(path):
763af6ab5fSopenharmony_ci    if os.path.exists(path):
773af6ab5fSopenharmony_ci        shutil.rmtree(path)
783af6ab5fSopenharmony_ci
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_cidef remove_file(file):
813af6ab5fSopenharmony_ci    if os.path.exists(file):
823af6ab5fSopenharmony_ci        os.remove(file)
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_cidef mkdir(path):
863af6ab5fSopenharmony_ci    if not os.path.exists(path):
873af6ab5fSopenharmony_ci        os.makedirs(path)
883af6ab5fSopenharmony_ci
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_cidef merge_files(file_list):
913af6ab5fSopenharmony_ci    base_file = file_list[0]
923af6ab5fSopenharmony_ci    with open(base_file, "a+") as output_file:
933af6ab5fSopenharmony_ci        for i in range(1, len(file_list)):
943af6ab5fSopenharmony_ci            with open(file_list[i], "r") as file:
953af6ab5fSopenharmony_ci                output_file.write(file.read())
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci
983af6ab5fSopenharmony_cidef pull_build_hermes():
993af6ab5fSopenharmony_ci    result = git_clone(HERMES_GIT_URL, HERMES_CLONE_PATH)
1003af6ab5fSopenharmony_ci    if not result:
1013af6ab5fSopenharmony_ci        return False
1023af6ab5fSopenharmony_ci    for cmd in BUILD_HERMES_CMDS:
1033af6ab5fSopenharmony_ci        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1043af6ab5fSopenharmony_ci        while True:
1053af6ab5fSopenharmony_ci            output = p.stdout.readline().decode()
1063af6ab5fSopenharmony_ci            if output == '' and p.poll() is not None:
1073af6ab5fSopenharmony_ci                break
1083af6ab5fSopenharmony_ci            if output:
1093af6ab5fSopenharmony_ci                write_log_file(HERMES_BUILD_LOG_PATH, f'{output.strip()} \n')
1103af6ab5fSopenharmony_ci        if p.returncode:
1113af6ab5fSopenharmony_ci            print(f"\n error: build hermes failed. {' '.join(cmd)}")
1123af6ab5fSopenharmony_ci            return False
1133af6ab5fSopenharmony_ci    return True
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_cidef pull_cases():
1173af6ab5fSopenharmony_ci    for case_git_info in CASE_URLS:
1183af6ab5fSopenharmony_ci        case_dir_name = case_git_info.get("name", None)
1193af6ab5fSopenharmony_ci        case_url = case_git_info.get("url", None)
1203af6ab5fSopenharmony_ci        if not case_dir_name or not case_url:
1213af6ab5fSopenharmony_ci            continue
1223af6ab5fSopenharmony_ci        dir_path = os.path.join(CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, case_dir_name)
1233af6ab5fSopenharmony_ci        if case_dir_name != SUNSPIDER:
1243af6ab5fSopenharmony_ci            clear_folder_shutil(dir_path)
1253af6ab5fSopenharmony_ci            clone_result = git_clone(case_url, dir_path)
1263af6ab5fSopenharmony_ci            if not clone_result:
1273af6ab5fSopenharmony_ci                return False
1283af6ab5fSopenharmony_ci        if case_dir_name == KRAKEN:
1293af6ab5fSopenharmony_ci            kraken_case_path = os.path.join(CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, SUNSPIDER)
1303af6ab5fSopenharmony_ci            shutil.copytree(dir_path, kraken_case_path)
1313af6ab5fSopenharmony_ci        if case_dir_name == KRAKEN:
1323af6ab5fSopenharmony_ci            tests_dir_path = os.path.join(dir_path, KRAKENBENCHMARK_CASE_PATH, KRAKEN_CASE_PATH)
1333af6ab5fSopenharmony_ci            filter_list = CASE_LIST.get(KRAKEN)
1343af6ab5fSopenharmony_ci        elif case_dir_name == SUNSPIDER:
1353af6ab5fSopenharmony_ci            tests_dir_path = os.path.join(dir_path, KRAKENBENCHMARK_CASE_PATH, SUNSPIDER_CASE_PATH)
1363af6ab5fSopenharmony_ci            filter_list = CASE_LIST.get(SUNSPIDER)
1373af6ab5fSopenharmony_ci        else:
1383af6ab5fSopenharmony_ci            tests_dir_path = dir_path
1393af6ab5fSopenharmony_ci            filter_list = CASE_LIST.get(case_dir_name)
1403af6ab5fSopenharmony_ci        filter_case(case_dir_name, tests_dir_path, dir_path, filter_list)
1413af6ab5fSopenharmony_ci    return True
1423af6ab5fSopenharmony_ci
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_cidef filter_case(case_dir_name, tests_dir_path, dir_path, case_list):
1453af6ab5fSopenharmony_ci    del_file_paths = []
1463af6ab5fSopenharmony_ci    if case_dir_name in [SUNSPIDER, KRAKEN]:
1473af6ab5fSopenharmony_ci        for file in os.listdir(tests_dir_path):
1483af6ab5fSopenharmony_ci            del_file_paths.append(process_file(file, case_list, dir_path, tests_dir_path))
1493af6ab5fSopenharmony_ci    for file in os.listdir(dir_path):
1503af6ab5fSopenharmony_ci        if file not in case_list:
1513af6ab5fSopenharmony_ci            del_file_paths.append(os.path.join(dir_path, file))
1523af6ab5fSopenharmony_ci        else:
1533af6ab5fSopenharmony_ci            case_path = os.path.join(dir_path, file)
1543af6ab5fSopenharmony_ci            case_data = case_path.replace(JS_FILE_SUFFIX, CASE_DATA_SUFFIX)
1553af6ab5fSopenharmony_ci            if os.path.exists(case_data):
1563af6ab5fSopenharmony_ci                merge_files([case_path, case_data])
1573af6ab5fSopenharmony_ci    delete_files(del_file_paths)
1583af6ab5fSopenharmony_ci
1593af6ab5fSopenharmony_ci
1603af6ab5fSopenharmony_cidef process_file(file, case_list, dir_path, tests_dir_path):
1613af6ab5fSopenharmony_ci    if file not in case_list:
1623af6ab5fSopenharmony_ci        return os.path.join(dir_path, file)
1633af6ab5fSopenharmony_ci    else:
1643af6ab5fSopenharmony_ci        need_case_path = os.path.join(tests_dir_path, file)
1653af6ab5fSopenharmony_ci        case_data_file = file.replace(JS_FILE_SUFFIX, CASE_DATA_SUFFIX)
1663af6ab5fSopenharmony_ci        need_case_data_path = os.path.join(tests_dir_path, case_data_file)
1673af6ab5fSopenharmony_ci        if os.path.exists(need_case_data_path):
1683af6ab5fSopenharmony_ci            merge_files([need_case_path, need_case_data_path])
1693af6ab5fSopenharmony_ci        shutil.move(need_case_path, dir_path)
1703af6ab5fSopenharmony_ci        return ''
1713af6ab5fSopenharmony_ci
1723af6ab5fSopenharmony_ci
1733af6ab5fSopenharmony_cidef delete_files(file_paths):
1743af6ab5fSopenharmony_ci    for file_path in file_paths:
1753af6ab5fSopenharmony_ci        if not file_path:
1763af6ab5fSopenharmony_ci            continue
1773af6ab5fSopenharmony_ci        if os.path.isdir(file_path):
1783af6ab5fSopenharmony_ci            remove_dir(file_path)
1793af6ab5fSopenharmony_ci        else:
1803af6ab5fSopenharmony_ci            remove_file(file_path)
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci
1833af6ab5fSopenharmony_cidef write_html(data, save_path, selected_params, info=False):
1843af6ab5fSopenharmony_ci    html_report = HTML_TEMPLATE + HTML_TABLE_DEFAULT
1853af6ab5fSopenharmony_ci    default_engine = True
1863af6ab5fSopenharmony_ci    result_data = data[ES2ABC]
1873af6ab5fSopenharmony_ci    result_data_len = len(result_data)
1883af6ab5fSopenharmony_ci    if len(data) > 1:
1893af6ab5fSopenharmony_ci        html_report = HTML_TEMPLATE + HTML_TABLE_COMP
1903af6ab5fSopenharmony_ci        default_engine = False
1913af6ab5fSopenharmony_ci        hermes_data = data[HERMES]
1923af6ab5fSopenharmony_ci        if result_data_len == len(hermes_data):
1933af6ab5fSopenharmony_ci            for i in range(result_data_len):
1943af6ab5fSopenharmony_ci                result_data[i] += hermes_data[i]
1953af6ab5fSopenharmony_ci        else:
1963af6ab5fSopenharmony_ci            print("Failed to generate comparison results, hermes or es2abc data is missing")
1973af6ab5fSopenharmony_ci            return False
1983af6ab5fSopenharmony_ci    html_report = html_report.replace(SELECTED_PARAMETERS_BASE, selected_params)
1993af6ab5fSopenharmony_ci    if info:
2003af6ab5fSopenharmony_ci        html_report = html_report.replace(DEFAULT_TIME, AVERAGE_TIME)
2013af6ab5fSopenharmony_ci    for row_data in result_data:
2023af6ab5fSopenharmony_ci        if not info:
2033af6ab5fSopenharmony_ci            html_report = f"""{html_report}<tr><td><a href="#" onclick="redirect(\'{row_data[0]}\')">{row_data[0]}</a>
2043af6ab5fSopenharmony_ci                        </td><td>{row_data[4]}</td><td>{row_data[1]} ms</td><td>{row_data[2]}</td>"""
2053af6ab5fSopenharmony_ci            if not default_engine:
2063af6ab5fSopenharmony_ci                html_report = f"{html_report}<td>{row_data[6]} ms</td><td>{row_data[7]}</td>"
2073af6ab5fSopenharmony_ci        else:
2083af6ab5fSopenharmony_ci            html_report = (f"{html_report}<tr><td>{row_data[0]}</td><td>{row_data[3]}</td><td>{row_data[1]} ms</td>"
2093af6ab5fSopenharmony_ci                           f"<td>{row_data[2]}</td>")
2103af6ab5fSopenharmony_ci            if not default_engine:
2113af6ab5fSopenharmony_ci                html_report = f"{html_report}<td>{row_data[5]} ms</td><td>{row_data[6]}</td>"
2123af6ab5fSopenharmony_ci        html_report = f"{html_report}</tr>"
2133af6ab5fSopenharmony_ci    html_report = f'{html_report}{HTML_SCRIPT}'
2143af6ab5fSopenharmony_ci    with open(save_path, 'w') as f:
2153af6ab5fSopenharmony_ci        f.write(html_report)
2163af6ab5fSopenharmony_ci    return True
2173af6ab5fSopenharmony_ci
218