1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import argparse 18import datetime 19import os 20import shutil 21import stat 22import subprocess 23import time 24import zipfile 25 26 27def parse_args(): 28 parser = argparse.ArgumentParser(description="Verify abc files in system app.") 29 parser.add_argument( 30 "--hap-dir", required=True, help="Path to the HAP files directory.") 31 parser.add_argument( 32 "--verifier-dir", required=True, help="Path to the ark_verifier directory.") 33 parser.add_argument( 34 "--keep-files", action="store_true", help="Keep extracted files after verification.") 35 return parser.parse_args() 36 37 38def copy_and_rename_hap_files(hap_folder, out_folder): 39 for file_path in os.listdir(hap_folder): 40 if file_path.endswith(".hap"): 41 destination_path = os.path.join(out_folder, file_path.replace(".hap", ".zip")) 42 shutil.copy(os.path.join(hap_folder, file_path), destination_path) 43 44 45def extract_zip(zip_path, extract_folder): 46 try: 47 with zipfile.ZipFile(zip_path, 'r') as zip_ref: 48 zip_ref.extractall(extract_folder) 49 except zipfile.BadZipFile as e: 50 print(f"Error extracting {zip_path}: {e}") 51 52 53def verify_file(file_path, ark_verifier_path): 54 verification_command = ["/usr/bin/time", "-v", ark_verifier_path, "--input_file", file_path] 55 result = subprocess.run(verification_command, capture_output=True, text=True) 56 status = 'pass' if result.returncode == 0 else 'fail' 57 58 memory_usage = None 59 user_time_ms = None 60 61 for line in result.stderr.splitlines(): 62 if "Maximum resident set size" in line: 63 memory_usage = f"{line.split(':')[1].strip()} KB" 64 if "User time (seconds)" in line: 65 user_time_seconds = float(line.split(":")[1].strip()) 66 user_time_ms = f"{user_time_seconds * 1000:.2f} ms" 67 68 file_size = os.path.getsize(file_path) 69 file_size_str = f"{file_size / 1024:.2f} KB" if file_size < 1024**2 else f"{file_size / 1024**2:.2f} MB" 70 report = { 71 "file": file_path, 72 "size": file_size_str, 73 "status": status, 74 "memory_usage": memory_usage, 75 "user_time": user_time_ms, 76 } 77 return report 78 79 80def process_directory(directory, ark_verifier_path): 81 total_count = 0 82 passed_count = 0 83 failed_abc_list = [] 84 report_list = [] 85 86 for root, dirs, files in os.walk(directory): 87 for file in files: 88 if not file.endswith(".abc"): 89 continue 90 abc_path = os.path.join(root, file) 91 print(f"Verifying file: {abc_path}") 92 report = verify_file(abc_path, ark_verifier_path) 93 report_list.append(report) 94 if report.get("status") == "pass": 95 passed_count += 1 96 else: 97 failed_abc_list.append(os.path.relpath(abc_path, directory)) 98 total_count += 1 99 100 return total_count, passed_count, failed_abc_list, report_list 101 102 103def verify_hap(hap_folder, ark_verifier_path): 104 failed_abc_list = [] 105 passed_count = 0 106 total_count = 0 107 report_list = [] 108 109 for file in os.listdir(hap_folder): 110 if not file.endswith(".zip"): 111 continue 112 113 zip_path = os.path.join(hap_folder, file) 114 extract_folder = os.path.join(hap_folder, file.replace(".zip", "")) 115 print(f"Extracting {zip_path} to {extract_folder}") 116 extract_zip(zip_path, extract_folder) 117 118 ets_path = os.path.join(extract_folder, "ets") 119 if not os.path.exists(ets_path): 120 continue 121 122 modules_abc_path = os.path.join(ets_path, "modules.abc") 123 if os.path.isfile(modules_abc_path): 124 print(f"Verifying file: {modules_abc_path}") 125 report = verify_file(modules_abc_path, ark_verifier_path) 126 report_list.append(report) 127 if report.get("status") == "pass": 128 passed_count += 1 129 else: 130 failed_abc_list.append(os.path.relpath(modules_abc_path, hap_folder)) 131 total_count += 1 132 else: 133 total_inc, passed_inc, failed_abc_inc, reports = process_directory(ets_path, ark_verifier_path) 134 total_count += total_inc 135 passed_count += passed_inc 136 failed_abc_list.extend(failed_abc_inc) 137 report_list.extend(reports) 138 139 return total_count, passed_count, len(failed_abc_list), failed_abc_list, report_list 140 141 142def save_report(report_list, report_file): 143 flags = os.O_RDWR | os.O_CREAT 144 mode = stat.S_IWUSR | stat.S_IRUSR 145 with os.fdopen(os.open(report_file, flags, mode), 'w') as f: 146 f.truncate() 147 f.write("<html><head><title>Verification Report</title>") 148 f.write("<style>") 149 f.write("body {font-family: Arial, sans-serif;}") 150 f.write("table {width: 100%; border-collapse: collapse;}") 151 f.write("th, td {border: 1px solid black; padding: 8px; text-align: left;}") 152 f.write("th {background-color: #f2f2f2;}") 153 f.write("tr:nth-child(even) {background-color: #f9f9f9;}") 154 f.write("tr:hover {background-color: #f1f1f1;}") 155 f.write("</style></head><body>\n") 156 f.write("<h1>Verification Report</h1>\n") 157 f.write(f"<p>Generated on: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>\n") 158 f.write("<table>\n") 159 f.write("<tr><th>File</th><th>Size</th><th>Status</th><th>Memory Usage</th><th>User Time</th></tr>\n") 160 for report in report_list: 161 f.write("<tr>") 162 f.write(f"<td>{report['file']}</td>") 163 f.write(f"<td>{report['size']}</td>") 164 f.write(f"<td>{report['status']}</td>") 165 f.write(f"<td>{report['memory_usage']}</td>") 166 f.write(f"<td>{report['user_time']}</td>") 167 f.write("</tr>\n") 168 f.write("</table>\n") 169 f.write("</body></html>\n") 170 171 172def main(): 173 start_time = time.time() 174 args = parse_args() 175 176 hap_folder_path = os.path.abspath(args.hap_dir) 177 ark_verifier_path = os.path.abspath(os.path.join(args.verifier_dir, "ark_verifier")) 178 179 script_dir = os.path.dirname(os.path.abspath(__file__)) 180 out_folder = os.path.join(script_dir, "out") 181 os.makedirs(out_folder, exist_ok=True) 182 183 copy_and_rename_hap_files(hap_folder_path, out_folder) 184 185 total_count, passed_count, failed_count, failed_abc_list, report_list = verify_hap(out_folder, ark_verifier_path) 186 187 print("Summary(abc verification):") 188 print(f"Total: {total_count}") 189 print(f"Passed: {passed_count}") 190 print(f"Failed: {failed_count}") 191 192 if failed_count > 0: 193 print("\nFailed abc files:") 194 for failed_abc in failed_abc_list: 195 print(f" - {failed_abc}") 196 197 report_file = os.path.join(script_dir, "verification_report.html") 198 save_report(report_list, report_file) 199 print(f"\nDetailed report saved to: {report_file}") 200 201 if not args.keep_files: 202 if os.path.isdir(out_folder): 203 shutil.rmtree(out_folder) 204 print(f"\n'{out_folder}' directory has been deleted.") 205 206 end_time = time.time() 207 duration = end_time - start_time 208 completion_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(end_time)) 209 210 print(f"\nExecution time: {duration:.2f} seconds") 211 print(f"Completion time: {completion_time}") 212 213 214if __name__ == "__main__": 215 main() 216