• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4"""
5Copyright (c) 2023 Huawei Device Co., Ltd.
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17"""
18import os
19import shutil
20import subprocess
21
22from config import BUILD_HERMES_CMDS, HERMES_BUILD_LOG_PATH, HERMES_CLONE_PATH, REPORT_DIR, LOG_FILE, \
23    CASE_URLS, CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, SUNSPIDER, KRAKEN, \
24    CASE_LIST, KRAKENBENCHMARK_CASE_PATH, KRAKEN_CASE_PATH, SUNSPIDER_CASE_PATH, JS_FILE_SUFFIX, \
25    CASE_DATA_SUFFIX, HTML_TEMPLATE, DEFAULT_TIME, AVERAGE_TIME, HTML_SCRIPT, SELECTED_PARAMETERS_BASE, \
26    HTML_TABLE_DEFAULT, HTML_TABLE_COMP, HERMES_GIT_URL, ES2ABC, HERMES
27
28
29def write_result(log_str):
30    write_log_file(os.path.join(REPORT_DIR, LOG_FILE), log_str)
31
32
33def write_log_file(file_path, log_str):
34    with open(file_path, mode='a+') as f:
35        f.write(log_str)
36
37
38def traverse_dir(path):
39    file_paths = {}
40    for file in os.listdir(path):
41        file_path = os.path.join(path, file)
42        if os.path.isdir(file_path):
43            file_paths.update(traverse_dir(file_path))
44        else:
45            dir_name = os.path.dirname(file_path)
46            if dir_name not in file_paths:
47                file_paths[dir_name] = [file_path]
48            else:
49                file_paths[dir_name].append(file_path)
50    return file_paths
51
52
53def run_cmd_cwd(cmds):
54    p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55    p.wait()
56    return p.returncode
57
58
59def git_clone(git_url, code_dir):
60    cmd = ['git', 'clone', git_url, code_dir]
61    ret = run_cmd_cwd(cmd)
62    result = True
63    if ret:
64        print(f"\n error: Cloning '{git_url}' failed.")
65        result = False
66    return result
67
68
69def clear_folder_shutil(path):
70    if os.path.exists(path):
71        shutil.rmtree(path)
72    os.mkdir(path)
73
74
75def remove_dir(path):
76    if os.path.exists(path):
77        shutil.rmtree(path)
78
79
80def remove_file(file):
81    if os.path.exists(file):
82        os.remove(file)
83
84
85def mkdir(path):
86    if not os.path.exists(path):
87        os.makedirs(path)
88
89
90def merge_files(file_list):
91    base_file = file_list[0]
92    with open(base_file, "a+") as output_file:
93        for i in range(1, len(file_list)):
94            with open(file_list[i], "r") as file:
95                output_file.write(file.read())
96
97
98def pull_build_hermes():
99    result = git_clone(HERMES_GIT_URL, HERMES_CLONE_PATH)
100    if not result:
101        return False
102    for cmd in BUILD_HERMES_CMDS:
103        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
104        while True:
105            output = p.stdout.readline().decode()
106            if output == '' and p.poll() is not None:
107                break
108            if output:
109                write_log_file(HERMES_BUILD_LOG_PATH, f'{output.strip()} \n')
110        if p.returncode:
111            print(f"\n error: build hermes failed. {' '.join(cmd)}")
112            return False
113    return True
114
115
116def pull_cases():
117    for case_git_info in CASE_URLS:
118        case_dir_name = case_git_info.get("name", None)
119        case_url = case_git_info.get("url", None)
120        if not case_dir_name or not case_url:
121            continue
122        dir_path = os.path.join(CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, case_dir_name)
123        if case_dir_name != SUNSPIDER:
124            clear_folder_shutil(dir_path)
125            clone_result = git_clone(case_url, dir_path)
126            if not clone_result:
127                return False
128        if case_dir_name == KRAKEN:
129            kraken_case_path = os.path.join(CUR_FILE_DIR, DEFAULT_TESTCASES_DIR, SUNSPIDER)
130            shutil.copytree(dir_path, kraken_case_path)
131        if case_dir_name == KRAKEN:
132            tests_dir_path = os.path.join(dir_path, KRAKENBENCHMARK_CASE_PATH, KRAKEN_CASE_PATH)
133            filter_list = CASE_LIST.get(KRAKEN)
134        elif case_dir_name == SUNSPIDER:
135            tests_dir_path = os.path.join(dir_path, KRAKENBENCHMARK_CASE_PATH, SUNSPIDER_CASE_PATH)
136            filter_list = CASE_LIST.get(SUNSPIDER)
137        else:
138            tests_dir_path = dir_path
139            filter_list = CASE_LIST.get(case_dir_name)
140        filter_case(case_dir_name, tests_dir_path, dir_path, filter_list)
141    return True
142
143
144def filter_case(case_dir_name, tests_dir_path, dir_path, case_list):
145    del_file_paths = []
146    if case_dir_name in [SUNSPIDER, KRAKEN]:
147        for file in os.listdir(tests_dir_path):
148            del_file_paths.append(process_file(file, case_list, dir_path, tests_dir_path))
149    for file in os.listdir(dir_path):
150        if file not in case_list:
151            del_file_paths.append(os.path.join(dir_path, file))
152        else:
153            case_path = os.path.join(dir_path, file)
154            case_data = case_path.replace(JS_FILE_SUFFIX, CASE_DATA_SUFFIX)
155            if os.path.exists(case_data):
156                merge_files([case_path, case_data])
157    delete_files(del_file_paths)
158
159
160def process_file(file, case_list, dir_path, tests_dir_path):
161    if file not in case_list:
162        return os.path.join(dir_path, file)
163    else:
164        need_case_path = os.path.join(tests_dir_path, file)
165        case_data_file = file.replace(JS_FILE_SUFFIX, CASE_DATA_SUFFIX)
166        need_case_data_path = os.path.join(tests_dir_path, case_data_file)
167        if os.path.exists(need_case_data_path):
168            merge_files([need_case_path, need_case_data_path])
169        shutil.move(need_case_path, dir_path)
170        return ''
171
172
173def delete_files(file_paths):
174    for file_path in file_paths:
175        if not file_path:
176            continue
177        if os.path.isdir(file_path):
178            remove_dir(file_path)
179        else:
180            remove_file(file_path)
181
182
183def write_html(data, save_path, selected_params, info=False):
184    html_report = HTML_TEMPLATE + HTML_TABLE_DEFAULT
185    default_engine = True
186    result_data = data[ES2ABC]
187    result_data_len = len(result_data)
188    if len(data) > 1:
189        html_report = HTML_TEMPLATE + HTML_TABLE_COMP
190        default_engine = False
191        hermes_data = data[HERMES]
192        if result_data_len == len(hermes_data):
193            for i in range(result_data_len):
194                result_data[i] += hermes_data[i]
195        else:
196            print("Failed to generate comparison results, hermes or es2abc data is missing")
197            return False
198    html_report = html_report.replace(SELECTED_PARAMETERS_BASE, selected_params)
199    if info:
200        html_report = html_report.replace(DEFAULT_TIME, AVERAGE_TIME)
201    for row_data in result_data:
202        if not info:
203            html_report = f"""{html_report}<tr><td><a href="#" onclick="redirect(\'{row_data[0]}\')">{row_data[0]}</a>
204                        </td><td>{row_data[4]}</td><td>{row_data[1]} ms</td><td>{row_data[2]}</td>"""
205            if not default_engine:
206                html_report = f"{html_report}<td>{row_data[6]} ms</td><td>{row_data[7]}</td>"
207        else:
208            html_report = (f"{html_report}<tr><td>{row_data[0]}</td><td>{row_data[3]}</td><td>{row_data[1]} ms</td>"
209                           f"<td>{row_data[2]}</td>")
210            if not default_engine:
211                html_report = f"{html_report}<td>{row_data[5]} ms</td><td>{row_data[6]}</td>"
212        html_report = f"{html_report}</tr>"
213    html_report = f'{html_report}{HTML_SCRIPT}'
214    with open(save_path, 'w') as f:
215        f.write(html_report)
216    return True
217
218