1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2024 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import os 20from .util import exec_command, compare_target_files, get_all_idl_files 21from .util import get_time_stamp, print_success, print_failure, dump_ast_compare 22from .util import get_idl, hdi_gen_fail_check_ignore_line 23 24 25__all__ = ["Test"] 26 27class Test: 28 def __init__(self): 29 self.name = self.__class__.__name__ 30 self._file_name = self.get_file_name() 31 self.working_dir = self.get_working_dir() 32 self._package_path = self.working_dir 33 self.idl_dir = os.path.join(self.working_dir, "foo") 34 self.output_dir = os.path.join(self.working_dir, "out") 35 self.target_dir = os.path.join(self.working_dir, "target") 36 self._system_attr = "full" 37 self._mode_attr = "ipc" 38 self._command_attr = "" 39 self._command_ext_attr = "" 40 self._gen_langauge = "--gen-cpp" 41 self._idl = get_idl() 42 self._command_format = "{} --intf-type hdi --system {} -m {} {} {} {} -r ohos.hdi:{} -d {}" 43 self.command = self._command_format.format(self._idl, self._system_attr, self._mode_attr, 44 self._command_attr, self._command_ext_attr, 45 self._gen_langauge, self._package_path, self.output_dir) 46 self._not_use_default_add_idl_file = False 47 self._output_path = None 48 self._hash_command_format = "{} --intf-type hdi --hash -r ohos.hdi:{} {} -o {}" 49 self._dump_ast_command_format = "{} --intf-type hdi --dump-ast -r ohos.hdi:{} {} {} -o {}" 50 self._dump_ast_check = False 51 self._check_fail_ignore_line = False 52 53 def get_file_name(self): 54 # 子类继承实现 55 return "" 56 57 def set_check_fail_ignore_line(self, attr): 58 self._check_fail_ignore_line = attr 59 60 def get_working_dir(self): 61 current_path = os.path.dirname(os.path.abspath(__file__)) 62 return os.path.realpath(os.path.join(current_path, 63 "..", os.path.splitext(os.path.basename(self._file_name))[0])) 64 65 def set_command_attr(self, attr): 66 self._command_attr = attr 67 68 def set_command_ext_attr(self, attr): 69 self._command_ext_attr = attr 70 71 def set_command_gen_langauge(self, langauge): 72 self._gen_langauge = langauge 73 74 def set_output_dir(self, output_dir): 75 self.output_dir = os.path.join(self.working_dir, output_dir) 76 77 def set_target_dir(self, target_dir): 78 self.target_dir = os.path.join(self.working_dir, target_dir) 79 80 def set_system_attr(self, attr): 81 self._system_attr = attr 82 83 def set_mode_attr(self, attr): 84 self._mode_attr = attr 85 86 def set_package_path(self, package_path): 87 self._package_path = package_path 88 89 def set_idl_dir(self, path): 90 self.idl_dir = path 91 92 def set_not_use_default_add_idl_file(self, opt): 93 self._not_use_default_add_idl_file = opt 94 95 def update_command(self): 96 self.command = self._command_format.format(self._idl, self._system_attr, self._mode_attr, 97 self._command_attr, self._command_ext_attr, 98 self._gen_langauge, self._package_path, self.output_dir) 99 100 def set_output_path(self, output_path): 101 self._output_path = output_path 102 103 def hash_command_update(self): 104 hash_command = self._hash_command_format.format(self._idl, self._package_path, 105 self._command_attr, self._output_path) 106 self.set_command(hash_command) 107 108 def dump_ast_command_update(self, use_tee=True): 109 dump_ast_command = self._dump_ast_command_format.format(self._idl, self._package_path, self._command_attr, 110 self._command_ext_attr, self._output_path) 111 if use_tee: 112 dump_ast_command += f" | tee {self._output_path}" 113 self.set_command(dump_ast_command) 114 115 def set_hash_param(self, package_path, command_attr): 116 self.set_package_path(package_path) 117 self.set_command_attr(f"-D {command_attr}") 118 output_path = os.path.join(self.working_dir, "hash_out") 119 if not os.path.exists(output_path): 120 os.makedirs(output_path) 121 self.set_output_path(os.path.join(output_path, "hash.txt")) 122 self.set_output_dir(output_path) 123 self.set_target_dir(os.path.join(self.working_dir, "hash_target")) 124 self.set_not_use_default_add_idl_file(True) 125 self.hash_command_update() 126 127 def set_dump_ast_check(self, if_check): 128 self._dump_ast_check = if_check 129 130 def set_dump_ast_param(self, package_path, command_attr, use_tee=True): 131 self.set_package_path(package_path) 132 self.set_command_attr(f"-D {command_attr}") 133 output_path = os.path.join(self.working_dir, "dump_ast_out") 134 if not os.path.exists(output_path): 135 os.makedirs(output_path) 136 self.set_output_path(os.path.join(output_path, "dump.txt")) 137 self.set_output_dir(output_path) 138 self.set_target_dir(os.path.join(self.working_dir, "dump_ast_target")) 139 self.set_not_use_default_add_idl_file(True) 140 self.set_dump_ast_check(True) 141 self.dump_ast_command_update(use_tee) 142 143 def set_command(self, command): 144 self.command = command 145 146 def set_gen_c_env(self): 147 self.set_command_gen_langauge("--gen-c") 148 self.set_output_dir("c_out") 149 self.set_target_dir("c_target") 150 self.update_command() 151 152 def set_gen_cpp_env(self): 153 self.set_command_gen_langauge("--gen-cpp") 154 self.set_output_dir("cpp_out") 155 self.set_target_dir("cpp_target") 156 self.update_command() 157 158 def set_gen_java_env(self): 159 self.set_command_gen_langauge("--gen-java") 160 self.set_output_dir("java_out") 161 self.set_target_dir("java_target") 162 self.update_command() 163 164 def run(self): 165 # please add test code here 166 return False 167 168 def run_choose(self, choose): 169 if choose: 170 return self.run_success() 171 return self.run_fail() 172 173 def run_success(self): 174 if not self._not_use_default_add_idl_file: 175 self.add_idl_files() 176 status, ret = exec_command(self.command) 177 if status != 0: 178 print_failure(f"[ERROR] command:{self.command} run err") 179 print_failure(f"[ERROR] {ret}") 180 return False 181 special_proc_func = None 182 if self._dump_ast_check: 183 special_proc_func = dump_ast_compare 184 if compare_target_files(self.output_dir, self.target_dir, special_proc_func): 185 return True 186 return False 187 188 def run_fail(self): 189 if not self._not_use_default_add_idl_file: 190 self.add_idl_files() 191 status, result = exec_command(self.command) 192 193 if status == 0: 194 print_failure(f"[ERROR] ret({status}) run cmd: {self.command}") 195 return False 196 197 expected_fail_output = "" 198 with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output: 199 expected_fail_output = target_output.read() 200 201 if self._check_fail_ignore_line: 202 ret = hdi_gen_fail_check_ignore_line(result, expected_fail_output) 203 if not ret: 204 print_failure(f"[ERROR] Expect ret: {expected_fail_output}") 205 print_failure(f"[ERROR] Actual ret: {result}") 206 return ret 207 208 if expected_fail_output != result: 209 print_failure(f"[ERROR] Expect ret: {expected_fail_output}") 210 print_failure(f"[ERROR] Actual ret: {result}") 211 return False 212 return True 213 214 def remove_output(self): 215 exec_command("rm -rf {}".format(self.output_dir)) 216 return True 217 218 def add_idl_files(self): 219 idl_list = get_all_idl_files(self.idl_dir) 220 for idl in idl_list: 221 self.command = "".join((self.command, " -c {}".format(idl))) 222 223 def test(self): 224 print_success("[ RUN ] {}".format(self.name)) 225 start_time = get_time_stamp() 226 result = self.run() 227 end_time = get_time_stamp() 228 229 if result: 230 print_success("[ OK ] {} ({}ms)".format(self.name, end_time - start_time)) 231 else: 232 print_failure("[ FAILED ] {} ({}ms)".format(self.name, end_time - start_time)) 233 return result 234