• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
20import shutil
21import re
22
23from util import exec_command, compare_target_files, file_exists
24from util import get_time_stamp, print_success, print_failure
25from util import get_idl
26
27
28class Test:
29    def __init__(self):
30        self.name = self.__class__.__name__
31        self._file_name = self.get_file_name()
32        self.working_dir = self.get_working_dir()
33        self.idl_file = os.path.join(self.working_dir, "foo", "IFoo.idl")
34        self.output_dir = os.path.join(self.working_dir, "out")
35        self.target_dir = os.path.join(self.working_dir, "target")
36        self._gen_langauge = "--gen-cpp"
37        self._idl = get_idl()
38        self._command_format = "{} {} --intf-type sa -c {} -d {}"
39        self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir)
40
41    def get_file_name(self):
42        # 子类继承实现
43        return ""
44
45    def get_working_dir(self):
46        current_path = os.path.dirname(os.path.abspath(__file__))
47        return os.path.join(current_path, os.path.splitext(os.path.basename(self._file_name))[0])
48
49    def set_command_attr(self, attr):
50        self._command_attr = attr
51
52    def set_command_gen_langauge(self, langauge):
53        self._gen_langauge = langauge
54
55    def set_output_dir(self, output_dir):
56        self.output_dir = os.path.join(self.working_dir, output_dir)
57
58    def set_target_dir(self, target_dir):
59        self.target_dir = os.path.join(self.working_dir, target_dir)
60
61    def set_idl_file(self, idl_file):
62        self.idl_file = os.path.join(self.working_dir, "foo", idl_file)
63
64    def update_command(self):
65        self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir)
66
67    def set_gen_c_env(self):
68        self.set_command_gen_langauge("--gen-c")
69        self.set_output_dir("out_c")
70        self.set_target_dir("target_c")
71        self.update_command()
72
73    def set_gen_cpp_env(self):
74        self.set_command_gen_langauge("--gen-cpp")
75        self.set_output_dir("out_cpp")
76        self.set_target_dir("target_cpp")
77        self.update_command()
78
79    def set_gen_rust_env(self):
80        self.set_command_gen_langauge("--gen-rust")
81        self.set_output_dir("out_rust")
82        self.set_target_dir("target_rust")
83        self.update_command()
84
85    def set_gen_ts_env(self):
86        self.set_command_gen_langauge("--gen-ts")
87        self.set_output_dir("out_ts")
88        self.set_target_dir("target_ts")
89        self.set_idl_file("IFooTs.idl")
90        self.update_command()
91
92    def set_cmd_test_env(self):
93        self._command_format = "{} --intf-type sa -c {} {}"
94        self.command = self._command_format.format(self._idl, self.idl_file, self._command_attr)
95
96    def run(self):
97        # please add test code here
98        return False
99
100    def run_choose(self, choose, no_output=False):
101        if choose:
102            result = self.run_success(no_output)
103        else:
104            result = self.run_fail()
105        self.remove_output()
106        return result
107
108    def deal_result(self, result):
109        # 子类继承实现
110        return result
111
112    def run_success(self, no_output=False):
113        status, result = exec_command(self.command)
114        expected_output = ""
115        if status != 0:
116            print_failure(f"[ERROR] command:{self.command} run err")
117            return False
118        if no_output is True:
119            return True
120        if file_exists(os.path.join(self.target_dir, "output.txt")):
121            with open(os.path.join(self.target_dir, "output.txt"), 'r') as target_output:
122                expected_output = target_output.read()
123            if self.deal_result(result) == expected_output:
124                return True
125            else:
126                print_failure(f"[ERROR] command:{self.command} not meet expectations")
127                return False
128        if 'type_import' in self.working_dir:
129            self.set_output_dir("out_file")
130            self.set_target_dir("target_file")
131        return compare_target_files(self.output_dir, self.target_dir)
132
133    def hdi_gen_fail_check_ignore_line(self, result: str, target: str):
134        fail_template = r"(.*): \[(\S+):\d+\] \[?(.*)error:(.*)"
135        result_lines = result.split("\n")
136        target_lines = target.split("\n")
137        if len(result_lines) != len(target_lines):
138            print_failure(f"[ERROR] result line(len(result_lines)) != target line(len(target_lines))")
139            return False
140
141        for result_line, target_line in zip(result_lines, target_lines):
142            lhd_obj = re.search(fail_template, result_line)
143            rhd_obj = re.search(fail_template, target_line)
144            if not lhd_obj and not rhd_obj:
145                if result_line == target_line:
146                    continue
147                else:
148                    print_failure(f"[ERROR] actual: {result_line}")
149                    print_failure(f"[ERROR] expect: {target_line}")
150                    return False
151            elif not lhd_obj or not rhd_obj:
152                print_failure(f"[ERROR] actual: {result_line}")
153                print_failure(f"[ERROR] expect: {target_line}")
154                return False
155            lhd_start_check_content = lhd_obj.group(1)
156            rhd_start_check_content = rhd_obj.group(1)
157            lhd_err_func_check_content = lhd_obj.group(2)
158            rhd_err_func_check_content = rhd_obj.group(2)
159            lhd_median_check_content = lhd_obj.group(3)
160            rhd_median_check_content = rhd_obj.group(3)
161            lhd_end_check_content = lhd_obj.group(4)
162            rhd_end_check_content = rhd_obj.group(4)
163            if lhd_start_check_content != rhd_start_check_content or \
164                lhd_err_func_check_content != rhd_err_func_check_content or \
165                lhd_median_check_content != rhd_median_check_content or \
166                lhd_end_check_content != rhd_end_check_content:
167                print_failure(f"[ERROR] actual: {result_line}")
168                print_failure(f"[ERROR] expect: {target_line}")
169                return False
170
171        return True
172
173    def run_fail(self):
174        status, result = exec_command(self.command)
175        expected_fail_output = ""
176        with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output:
177            expected_fail_output = target_output.read()
178
179        if status != 0 and self.hdi_gen_fail_check_ignore_line(result, expected_fail_output):
180            return True
181        return False
182
183    def remove_output(self):
184        if os.path.exists(self.output_dir):
185            shutil.rmtree(self.output_dir)
186
187    def test(self):
188        print_success("[ RUN       ] {}".format(self.name))
189        start_time = get_time_stamp()
190        result = self.run()
191        end_time = get_time_stamp()
192
193        if result:
194            print_success("[        OK ] {} ({}ms)".format(self.name, end_time - start_time))
195        else:
196            print_failure("[    FAILED ] {} ({}ms)".format(self.name, end_time - start_time))
197        return result
198