1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# 6# HDF is dual licensed: you can use it either under the terms of 7# the GPL, or the BSD license, at your option. 8# See the LICENSE file in the root of this repository for complete details. 9 10import os 11import subprocess 12import time 13 14 15def get_time_stamp(): 16 return int(round(time.time() * 1000)) 17 18 19def print_success(info): 20 print("\033[32m{}\033[0m".format(info)) 21 22 23def print_failure(info): 24 print("\033[31m{}\033[0m".format(info)) 25 26 27def is_subsequence(first_file, second_file): 28 first_info = first_file.read() 29 second_info = second_file.readline() 30 while second_info: 31 if first_info.find(second_info) == -1: 32 print("line\n", second_info, "is not in output file") 33 return False 34 second_info = second_file.readline() 35 return True 36 37 38def compare_file(first_file_path, second_file_path): 39 with open(first_file_path, 'r') as first_file: 40 with open(second_file_path, 'r') as second_file: 41 return is_subsequence(first_file, second_file) 42 43 44def compare_target_files(first_file_path, second_file_path): 45 first_files_list = get_all_files(first_file_path) 46 second_files_list = get_all_files(second_file_path) 47 48 first_files = set([file[len(first_file_path):] for file in first_files_list]) 49 second_files = set([file[len(second_file_path):-4] for file in second_files_list]) 50 51 common_files = first_files & second_files 52 53 for files in common_files: 54 if not compare_file("{}{}".format(first_file_path, files), "{}{}.txt".format(second_file_path, files)): 55 print("file ", "{}{}".format(first_file_path, files), "{}{}.txt".format(second_file_path, files), \ 56 "is different") 57 return False 58 return True 59 60 61def exec_command(command): 62 return subprocess.getstatusoutput(command) 63 64 65def file_exists(file_path): 66 return os.path.isfile(file_path) 67 68 69def make_binary_file(file_path): 70 print("making hdi-gen...") 71 return exec_command("make --directory={} --jobs=4".format(file_path)) 72 73 74def clean_binary_file(file_path): 75 return exec_command("make --directory={} clean".format(file_path)) 76 77 78def get_all_files(path): 79 file_list = [] 80 items = os.listdir(path) 81 for item in items: 82 item_path = os.path.join(path, item) 83 if not os.path.isdir(item_path): 84 file_list.append(item_path) 85 else: 86 file_list += get_all_files(item_path) 87 return file_list 88 89 90def get_all_idl_files(idl_path): 91 file_list = get_all_files(idl_path) 92 idl_file_list = [] 93 for file in file_list: 94 if os.path.splitext(file)[-1] == ".idl": 95 idl_file_list.append(file) 96 return idl_file_list 97 98 99 100class Test: 101 def __init__(self, name, working_dir): 102 self.name = name 103 self.working_dir = working_dir 104 self.idl_dir = os.path.join(self.working_dir, "foo") 105 self.output_dir = os.path.join(working_dir, "out") 106 self.target_dir = os.path.join(working_dir, "target") 107 self.command = "../../hdi-gen -s full -m ipc -l cpp -r ohos.hdi:{} -d {}".format(working_dir, self.output_dir) 108 109 def run(self): 110 # please add test code here 111 return False 112 113 def run_success(self): 114 self.add_idl_files() 115 status, _ = exec_command(self.command) 116 if status == 0 and compare_target_files(self.output_dir, self.target_dir): 117 return True 118 return False 119 120 def run_fail(self): 121 self.add_idl_files() 122 status, _ = exec_command(self.command) 123 124 expected_fail_output = "" 125 with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output: 126 expected_fail_output = target_output.read() 127 128 if status != 0 and expected_fail_output == _: 129 return True 130 return False 131 132 def remove_output(self): 133 exec_command("rm -rf {}".format(self.output_dir)) 134 return True 135 136 def add_idl_files(self): 137 idl_list = get_all_idl_files(self.idl_dir) 138 for idl in idl_list: 139 self.command = "".join((self.command, " -c {}".format(idl))) 140 141 def test(self): 142 print_success("[ RUN ] {}".format(self.name)) 143 start_time = get_time_stamp() 144 result = self.run() 145 end_time = get_time_stamp() 146 147 if result: 148 print_success("[ OK ] {} ({}ms)".format(self.name, end_time - start_time)) 149 else: 150 print_failure("[ FAILED ] {} ({}ms)".format(self.name, end_time - start_time)) 151 return result 152 153 154# compile empty idl file 155class UnitTest01(Test): 156 def run(self): 157 return self.run_fail() 158 159 160# standard interface idl file 161class UnitTest02(Test): 162 def run(self): 163 return self.run_success() 164 165 166# standard callback idl file 167class UnitTest03(Test): 168 def run(self): 169 return self.run_success() 170 171 172# extended interface idl file 173class UnitTest04(Test): 174 def run(self): 175 return self.run_success() 176 177 178# interface with types idl file 179class UnitTest05(Test): 180 def run(self): 181 return self.run_success() 182 183 184# extended enum idl file 185class UnitTest06(Test): 186 def run(self): 187 return self.run_success() 188 189 190# extended struct idl file 191class UnitTest07(Test): 192 def run(self): 193 return self.run_success() 194 195 196# overload method idl file 197class UnitTest08(Test): 198 def run(self): 199 return self.run_success() 200 201 202# enum nesting idl file 203class UnitTest09(Test): 204 def run(self): 205 return self.run_success() 206 207 208class Tests: 209 test_cases = [ 210 UnitTest01("UnitTestEmptyIdl", "01_empty_idl"), 211 UnitTest02("UnitTestStandardInterface", "02_standard_interface_idl"), 212 UnitTest03("UnitTestStandardCallback", "03_standard_callback_idl"), 213 UnitTest04("UnitTestExtendedInterface", "04_extended_interface_idl"), 214 UnitTest05("UnitTestTypesIdl", "05_types_idl"), 215 UnitTest06("UnitTestEnumExtension", "06_extended_enum_idl"), 216 UnitTest07("UnitTestStructExtension", "07_extended_struct_idl"), 217 UnitTest08("UnitTestOverloadMethod", "08_overload_method_idl"), 218 UnitTest09("UnitTestEnumNesting", "09_enum_nesting_idl"), 219 ] 220 221 @staticmethod 222 def set_up_test_case(): 223 hdi_gen_file = "../../hdi-gen" 224 ret = file_exists(hdi_gen_file) 225 if not ret: 226 hdi_gen_path = "../../" 227 if make_binary_file(hdi_gen_path)[0] == 0: 228 ret = True 229 if not ret: 230 print_failure("[===========] failed to make hdi-gen") 231 return ret 232 233 @staticmethod 234 def tear_down_test_case(): 235 for case in Tests.test_cases: 236 case.remove_output() 237 hdi_gen_path = "../../" 238 clean_binary_file(hdi_gen_path) 239 240 @staticmethod 241 def test(): 242 test_case_num = len(Tests.test_cases) 243 success_case_num = 0 244 print_success("[===========] start {} test".format(test_case_num)) 245 for test_case in Tests.test_cases: 246 if test_case.test(): 247 success_case_num += 1 248 print_success("[ PASSED ] {} test".format(success_case_num)) 249 failure_case_num = test_case_num - success_case_num 250 if failure_case_num > 0: 251 print_failure("[ FAILED ] {} test".format(failure_case_num)) 252 253 254if __name__ == "__main__": 255 if not Tests.set_up_test_case(): 256 print_failure("test case set up failed!") 257 exit(-1) 258 Tests.test() 259 Tests.tear_down_test_case() 260