1ca0551cfSopenharmony_ci#!/usr/bin/env python3
2ca0551cfSopenharmony_ci# -*- coding: utf-8 -*-
3ca0551cfSopenharmony_ci
4ca0551cfSopenharmony_ci#
5ca0551cfSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd.
6ca0551cfSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
7ca0551cfSopenharmony_ci# you may not use this file except in compliance with the License.
8ca0551cfSopenharmony_ci# You may obtain a copy of the License at
9ca0551cfSopenharmony_ci#
10ca0551cfSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
11ca0551cfSopenharmony_ci#
12ca0551cfSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
13ca0551cfSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
14ca0551cfSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15ca0551cfSopenharmony_ci# See the License for the specific language governing permissions and
16ca0551cfSopenharmony_ci# limitations under the License.
17ca0551cfSopenharmony_ci#
18ca0551cfSopenharmony_ci
19ca0551cfSopenharmony_ciimport os
20ca0551cfSopenharmony_ciimport shutil
21ca0551cfSopenharmony_ciimport re
22ca0551cfSopenharmony_ci
23ca0551cfSopenharmony_cifrom util import exec_command, compare_target_files, file_exists
24ca0551cfSopenharmony_cifrom util import get_time_stamp, print_success, print_failure
25ca0551cfSopenharmony_cifrom util import get_idl
26ca0551cfSopenharmony_ci
27ca0551cfSopenharmony_ci
28ca0551cfSopenharmony_ciclass Test:
29ca0551cfSopenharmony_ci    def __init__(self):
30ca0551cfSopenharmony_ci        self.name = self.__class__.__name__
31ca0551cfSopenharmony_ci        self._file_name = self.get_file_name()
32ca0551cfSopenharmony_ci        self.working_dir = self.get_working_dir()
33ca0551cfSopenharmony_ci        self.idl_file = os.path.join(self.working_dir, "foo", "IFoo.idl")
34ca0551cfSopenharmony_ci        self.output_dir = os.path.join(self.working_dir, "out")
35ca0551cfSopenharmony_ci        self.target_dir = os.path.join(self.working_dir, "target")
36ca0551cfSopenharmony_ci        self._gen_langauge = "--gen-cpp"
37ca0551cfSopenharmony_ci        self._idl = get_idl()
38ca0551cfSopenharmony_ci        self._command_format = "{} {} --intf-type sa -c {} -d {}"
39ca0551cfSopenharmony_ci        self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir)
40ca0551cfSopenharmony_ci
41ca0551cfSopenharmony_ci    def get_file_name(self):
42ca0551cfSopenharmony_ci        # 子类继承实现
43ca0551cfSopenharmony_ci        return ""
44ca0551cfSopenharmony_ci
45ca0551cfSopenharmony_ci    def get_working_dir(self):
46ca0551cfSopenharmony_ci        current_path = os.path.dirname(os.path.abspath(__file__))
47ca0551cfSopenharmony_ci        return os.path.join(current_path, os.path.splitext(os.path.basename(self._file_name))[0])
48ca0551cfSopenharmony_ci
49ca0551cfSopenharmony_ci    def set_command_attr(self, attr):
50ca0551cfSopenharmony_ci        self._command_attr = attr
51ca0551cfSopenharmony_ci
52ca0551cfSopenharmony_ci    def set_command_gen_langauge(self, langauge):
53ca0551cfSopenharmony_ci        self._gen_langauge = langauge
54ca0551cfSopenharmony_ci
55ca0551cfSopenharmony_ci    def set_output_dir(self, output_dir):
56ca0551cfSopenharmony_ci        self.output_dir = os.path.join(self.working_dir, output_dir)
57ca0551cfSopenharmony_ci
58ca0551cfSopenharmony_ci    def set_target_dir(self, target_dir):
59ca0551cfSopenharmony_ci        self.target_dir = os.path.join(self.working_dir, target_dir)
60ca0551cfSopenharmony_ci
61ca0551cfSopenharmony_ci    def set_idl_file(self, idl_file):
62ca0551cfSopenharmony_ci        self.idl_file = os.path.join(self.working_dir, "foo", idl_file)
63ca0551cfSopenharmony_ci
64ca0551cfSopenharmony_ci    def update_command(self):
65ca0551cfSopenharmony_ci        self.command = self._command_format.format(self._idl, self._gen_langauge, self.idl_file, self.output_dir)
66ca0551cfSopenharmony_ci
67ca0551cfSopenharmony_ci    def set_gen_c_env(self):
68ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-c")
69ca0551cfSopenharmony_ci        self.set_output_dir("out_c")
70ca0551cfSopenharmony_ci        self.set_target_dir("target_c")
71ca0551cfSopenharmony_ci        self.update_command()
72ca0551cfSopenharmony_ci
73ca0551cfSopenharmony_ci    def set_gen_cpp_env(self):
74ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-cpp")
75ca0551cfSopenharmony_ci        self.set_output_dir("out_cpp")
76ca0551cfSopenharmony_ci        self.set_target_dir("target_cpp")
77ca0551cfSopenharmony_ci        self.update_command()
78ca0551cfSopenharmony_ci
79ca0551cfSopenharmony_ci    def set_gen_rust_env(self):
80ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-rust")
81ca0551cfSopenharmony_ci        self.set_output_dir("out_rust")
82ca0551cfSopenharmony_ci        self.set_target_dir("target_rust")
83ca0551cfSopenharmony_ci        self.update_command()
84ca0551cfSopenharmony_ci
85ca0551cfSopenharmony_ci    def set_gen_ts_env(self):
86ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-ts")
87ca0551cfSopenharmony_ci        self.set_output_dir("out_ts")
88ca0551cfSopenharmony_ci        self.set_target_dir("target_ts")
89ca0551cfSopenharmony_ci        self.set_idl_file("IFooTs.idl")
90ca0551cfSopenharmony_ci        self.update_command()
91ca0551cfSopenharmony_ci
92ca0551cfSopenharmony_ci    def set_cmd_test_env(self):
93ca0551cfSopenharmony_ci        self._command_format = "{} --intf-type sa -c {} {}"
94ca0551cfSopenharmony_ci        self.command = self._command_format.format(self._idl, self.idl_file, self._command_attr)
95ca0551cfSopenharmony_ci
96ca0551cfSopenharmony_ci    def run(self):
97ca0551cfSopenharmony_ci        # please add test code here
98ca0551cfSopenharmony_ci        return False
99ca0551cfSopenharmony_ci
100ca0551cfSopenharmony_ci    def run_choose(self, choose, no_output=False):
101ca0551cfSopenharmony_ci        if choose:
102ca0551cfSopenharmony_ci            result = self.run_success(no_output)
103ca0551cfSopenharmony_ci        else:
104ca0551cfSopenharmony_ci            result = self.run_fail()
105ca0551cfSopenharmony_ci        self.remove_output()
106ca0551cfSopenharmony_ci        return result
107ca0551cfSopenharmony_ci
108ca0551cfSopenharmony_ci    def deal_result(self, result):
109ca0551cfSopenharmony_ci        # 子类继承实现
110ca0551cfSopenharmony_ci        return result
111ca0551cfSopenharmony_ci
112ca0551cfSopenharmony_ci    def run_success(self, no_output=False):
113ca0551cfSopenharmony_ci        status, result = exec_command(self.command)
114ca0551cfSopenharmony_ci        expected_output = ""
115ca0551cfSopenharmony_ci        if status != 0:
116ca0551cfSopenharmony_ci            print_failure(f"[ERROR] command:{self.command} run err")
117ca0551cfSopenharmony_ci            return False
118ca0551cfSopenharmony_ci        if no_output is True:
119ca0551cfSopenharmony_ci            return True
120ca0551cfSopenharmony_ci        if file_exists(os.path.join(self.target_dir, "output.txt")):
121ca0551cfSopenharmony_ci            with open(os.path.join(self.target_dir, "output.txt"), 'r') as target_output:
122ca0551cfSopenharmony_ci                expected_output = target_output.read()
123ca0551cfSopenharmony_ci            if self.deal_result(result) == expected_output:
124ca0551cfSopenharmony_ci                return True
125ca0551cfSopenharmony_ci            else:
126ca0551cfSopenharmony_ci                print_failure(f"[ERROR] command:{self.command} not meet expectations")
127ca0551cfSopenharmony_ci                return False
128ca0551cfSopenharmony_ci        return compare_target_files(self.output_dir, self.target_dir)
129ca0551cfSopenharmony_ci
130ca0551cfSopenharmony_ci    def hdi_gen_fail_check_ignore_line(self, result: str, target: str):
131ca0551cfSopenharmony_ci        fail_template = r"(.*): \[(\S+):\d+\] \[?(.*)error:(.*)"
132ca0551cfSopenharmony_ci        result_lines = result.split("\n")
133ca0551cfSopenharmony_ci        target_lines = target.split("\n")
134ca0551cfSopenharmony_ci        if len(result_lines) != len(target_lines):
135ca0551cfSopenharmony_ci            print_failure(f"[ERROR] result line(len(result_lines)) != target line(len(target_lines))")
136ca0551cfSopenharmony_ci            return False
137ca0551cfSopenharmony_ci
138ca0551cfSopenharmony_ci        for result_line, target_line in zip(result_lines, target_lines):
139ca0551cfSopenharmony_ci            lhd_obj = re.search(fail_template, result_line)
140ca0551cfSopenharmony_ci            rhd_obj = re.search(fail_template, target_line)
141ca0551cfSopenharmony_ci            if not lhd_obj and not rhd_obj:
142ca0551cfSopenharmony_ci                if result_line == target_line:
143ca0551cfSopenharmony_ci                    continue
144ca0551cfSopenharmony_ci                else:
145ca0551cfSopenharmony_ci                    print_failure(f"[ERROR] actual: {result_line}")
146ca0551cfSopenharmony_ci                    print_failure(f"[ERROR] expect: {target_line}")
147ca0551cfSopenharmony_ci                    return False
148ca0551cfSopenharmony_ci            elif not lhd_obj or not rhd_obj:
149ca0551cfSopenharmony_ci                print_failure(f"[ERROR] actual: {result_line}")
150ca0551cfSopenharmony_ci                print_failure(f"[ERROR] expect: {target_line}")
151ca0551cfSopenharmony_ci                return False
152ca0551cfSopenharmony_ci            lhd_start_check_content = lhd_obj.group(1)
153ca0551cfSopenharmony_ci            rhd_start_check_content = rhd_obj.group(1)
154ca0551cfSopenharmony_ci            lhd_err_func_check_content = lhd_obj.group(2)
155ca0551cfSopenharmony_ci            rhd_err_func_check_content = rhd_obj.group(2)
156ca0551cfSopenharmony_ci            lhd_median_check_content = lhd_obj.group(3)
157ca0551cfSopenharmony_ci            rhd_median_check_content = rhd_obj.group(3)
158ca0551cfSopenharmony_ci            lhd_end_check_content = lhd_obj.group(4)
159ca0551cfSopenharmony_ci            rhd_end_check_content = rhd_obj.group(4)
160ca0551cfSopenharmony_ci            if lhd_start_check_content != rhd_start_check_content or \
161ca0551cfSopenharmony_ci                lhd_err_func_check_content != rhd_err_func_check_content or \
162ca0551cfSopenharmony_ci                lhd_median_check_content != rhd_median_check_content or \
163ca0551cfSopenharmony_ci                lhd_end_check_content != rhd_end_check_content:
164ca0551cfSopenharmony_ci                print_failure(f"[ERROR] actual: {result_line}")
165ca0551cfSopenharmony_ci                print_failure(f"[ERROR] expect: {target_line}")
166ca0551cfSopenharmony_ci                return False
167ca0551cfSopenharmony_ci
168ca0551cfSopenharmony_ci        return True
169ca0551cfSopenharmony_ci
170ca0551cfSopenharmony_ci    def run_fail(self):
171ca0551cfSopenharmony_ci        status, result = exec_command(self.command)
172ca0551cfSopenharmony_ci        expected_fail_output = ""
173ca0551cfSopenharmony_ci        with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output:
174ca0551cfSopenharmony_ci            expected_fail_output = target_output.read()
175ca0551cfSopenharmony_ci
176ca0551cfSopenharmony_ci        if status != 0 and self.hdi_gen_fail_check_ignore_line(result, expected_fail_output):
177ca0551cfSopenharmony_ci            return True
178ca0551cfSopenharmony_ci        return False
179ca0551cfSopenharmony_ci
180ca0551cfSopenharmony_ci    def remove_output(self):
181ca0551cfSopenharmony_ci        if os.path.exists(self.output_dir):
182ca0551cfSopenharmony_ci            shutil.rmtree(self.output_dir)
183ca0551cfSopenharmony_ci
184ca0551cfSopenharmony_ci    def test(self):
185ca0551cfSopenharmony_ci        print_success("[ RUN       ] {}".format(self.name))
186ca0551cfSopenharmony_ci        start_time = get_time_stamp()
187ca0551cfSopenharmony_ci        result = self.run()
188ca0551cfSopenharmony_ci        end_time = get_time_stamp()
189ca0551cfSopenharmony_ci
190ca0551cfSopenharmony_ci        if result:
191ca0551cfSopenharmony_ci            print_success("[        OK ] {} ({}ms)".format(self.name, end_time - start_time))
192ca0551cfSopenharmony_ci        else:
193ca0551cfSopenharmony_ci            print_failure("[    FAILED ] {} ({}ms)".format(self.name, end_time - start_time))
194ca0551cfSopenharmony_ci        return result
195