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