#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Copyright (c) 2024 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import os import shutil import re from util import exec_command, compare_target_files, file_exists from util import get_time_stamp, print_success, print_failure from util import get_idl class Test: def __init__(self): self.name = self.__class__.__name__ self._file_name = self.get_file_name() self.working_dir = self.get_working_dir() self.idl_file = os.path.join(self.working_dir, "foo", "IFoo.idl") self.output_dir = os.path.join(self.working_dir, "out") self.target_dir = os.path.join(self.working_dir, "target") self._gen_langauge = "--gen-cpp" self._idl = get_idl() self._command_format = "{} {} --intf-type sa -c {} -d {}" self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir) def get_file_name(self): # 子类继承实现 return "" def get_working_dir(self): current_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(current_path, os.path.splitext(os.path.basename(self._file_name))[0]) def set_command_attr(self, attr): self._command_attr = attr def set_command_gen_langauge(self, langauge): self._gen_langauge = langauge def set_output_dir(self, output_dir): self.output_dir = os.path.join(self.working_dir, output_dir) def set_target_dir(self, target_dir): self.target_dir = os.path.join(self.working_dir, target_dir) def set_idl_file(self, idl_file): self.idl_file = os.path.join(self.working_dir, "foo", idl_file) def update_command(self): self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir) def set_gen_c_env(self): self.set_command_gen_langauge("--gen-c") self.set_output_dir("out_c") self.set_target_dir("target_c") self.update_command() def set_gen_cpp_env(self): self.set_command_gen_langauge("--gen-cpp") self.set_output_dir("out_cpp") self.set_target_dir("target_cpp") self.update_command() def set_gen_rust_env(self): self.set_command_gen_langauge("--gen-rust") self.set_output_dir("out_rust") self.set_target_dir("target_rust") self.update_command() def set_gen_ts_env(self): self.set_command_gen_langauge("--gen-ts") self.set_output_dir("out_ts") self.set_target_dir("target_ts") self.set_idl_file("IFooTs.idl") self.update_command() def set_cmd_test_env(self): self._command_format = "{} --intf-type sa -c {} {}" self.command = self._command_format.format(self._idl, self.idl_file, self._command_attr) def run(self): # please add test code here return False def run_choose(self, choose, no_output=False): if choose: result = self.run_success(no_output) else: result = self.run_fail() self.remove_output() return result def deal_result(self, result): # 子类继承实现 return result def run_success(self, no_output=False): status, result = exec_command(self.command) expected_output = "" if status != 0: print_failure(f"[ERROR] command:{self.command} run err") return False if no_output is True: return True if file_exists(os.path.join(self.target_dir, "output.txt")): with open(os.path.join(self.target_dir, "output.txt"), 'r') as target_output: expected_output = target_output.read() if self.deal_result(result) == expected_output: return True else: print_failure(f"[ERROR] command:{self.command} not meet expectations") return False return compare_target_files(self.output_dir, self.target_dir) def hdi_gen_fail_check_ignore_line(self, result: str, target: str): fail_template = r"(.*): \[(\S+):\d+\] \[?(.*)error:(.*)" result_lines = result.split("\n") target_lines = target.split("\n") if len(result_lines) != len(target_lines): print_failure(f"[ERROR] result line(len(result_lines)) != target line(len(target_lines))") return False for result_line, target_line in zip(result_lines, target_lines): lhd_obj = re.search(fail_template, result_line) rhd_obj = re.search(fail_template, target_line) if not lhd_obj and not rhd_obj: if result_line == target_line: continue else: print_failure(f"[ERROR] actual: {result_line}") print_failure(f"[ERROR] expect: {target_line}") return False elif not lhd_obj or not rhd_obj: print_failure(f"[ERROR] actual: {result_line}") print_failure(f"[ERROR] expect: {target_line}") return False lhd_start_check_content = lhd_obj.group(1) rhd_start_check_content = rhd_obj.group(1) lhd_err_func_check_content = lhd_obj.group(2) rhd_err_func_check_content = rhd_obj.group(2) lhd_median_check_content = lhd_obj.group(3) rhd_median_check_content = rhd_obj.group(3) lhd_end_check_content = lhd_obj.group(4) rhd_end_check_content = rhd_obj.group(4) if lhd_start_check_content != rhd_start_check_content or \ lhd_err_func_check_content != rhd_err_func_check_content or \ lhd_median_check_content != rhd_median_check_content or \ lhd_end_check_content != rhd_end_check_content: print_failure(f"[ERROR] actual: {result_line}") print_failure(f"[ERROR] expect: {target_line}") return False return True def run_fail(self): status, result = exec_command(self.command) expected_fail_output = "" with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output: expected_fail_output = target_output.read() if status != 0 and self.hdi_gen_fail_check_ignore_line(result, expected_fail_output): return True return False def remove_output(self): if os.path.exists(self.output_dir): shutil.rmtree(self.output_dir) def test(self): print_success("[ RUN ] {}".format(self.name)) start_time = get_time_stamp() result = self.run() end_time = get_time_stamp() if result: print_success("[ OK ] {} ({}ms)".format(self.name, end_time - start_time)) else: print_failure("[ FAILED ] {} ({}ms)".format(self.name, end_time - start_time)) return result