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_cifrom .util import exec_command, compare_target_files, get_all_idl_files
21ca0551cfSopenharmony_cifrom .util import get_time_stamp, print_success, print_failure, dump_ast_compare
22ca0551cfSopenharmony_cifrom .util import get_idl, hdi_gen_fail_check_ignore_line
23ca0551cfSopenharmony_ci
24ca0551cfSopenharmony_ci
25ca0551cfSopenharmony_ci__all__ = ["Test"]
26ca0551cfSopenharmony_ci
27ca0551cfSopenharmony_ciclass Test:
28ca0551cfSopenharmony_ci    def __init__(self):
29ca0551cfSopenharmony_ci        self.name = self.__class__.__name__
30ca0551cfSopenharmony_ci        self._file_name = self.get_file_name()
31ca0551cfSopenharmony_ci        self.working_dir = self.get_working_dir()
32ca0551cfSopenharmony_ci        self._package_path = self.working_dir
33ca0551cfSopenharmony_ci        self.idl_dir = os.path.join(self.working_dir, "foo")
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._system_attr = "full"
37ca0551cfSopenharmony_ci        self._mode_attr = "ipc"
38ca0551cfSopenharmony_ci        self._command_attr = ""
39ca0551cfSopenharmony_ci        self._command_ext_attr = ""
40ca0551cfSopenharmony_ci        self._gen_langauge = "--gen-cpp"
41ca0551cfSopenharmony_ci        self._idl = get_idl()
42ca0551cfSopenharmony_ci        self._command_format = "{} --intf-type hdi --system {} -m {} {} {} {} -r ohos.hdi:{} -d {}"
43ca0551cfSopenharmony_ci        self.command = self._command_format.format(self._idl, self._system_attr, self._mode_attr,
44ca0551cfSopenharmony_ci                                                   self._command_attr, self._command_ext_attr,
45ca0551cfSopenharmony_ci                                                   self._gen_langauge, self._package_path, self.output_dir)
46ca0551cfSopenharmony_ci        self._not_use_default_add_idl_file = False
47ca0551cfSopenharmony_ci        self._output_path = None
48ca0551cfSopenharmony_ci        self._hash_command_format = "{} --intf-type hdi --hash -r ohos.hdi:{} {} -o {}"
49ca0551cfSopenharmony_ci        self._dump_ast_command_format = "{} --intf-type hdi --dump-ast -r ohos.hdi:{} {} {} -o {}"
50ca0551cfSopenharmony_ci        self._dump_ast_check = False
51ca0551cfSopenharmony_ci        self._check_fail_ignore_line = False
52ca0551cfSopenharmony_ci
53ca0551cfSopenharmony_ci    def get_file_name(self):
54ca0551cfSopenharmony_ci        # 子类继承实现
55ca0551cfSopenharmony_ci        return ""
56ca0551cfSopenharmony_ci
57ca0551cfSopenharmony_ci    def set_check_fail_ignore_line(self, attr):
58ca0551cfSopenharmony_ci        self._check_fail_ignore_line = attr
59ca0551cfSopenharmony_ci
60ca0551cfSopenharmony_ci    def get_working_dir(self):
61ca0551cfSopenharmony_ci        current_path = os.path.dirname(os.path.abspath(__file__))
62ca0551cfSopenharmony_ci        return os.path.realpath(os.path.join(current_path,
63ca0551cfSopenharmony_ci                                             "..", os.path.splitext(os.path.basename(self._file_name))[0]))
64ca0551cfSopenharmony_ci
65ca0551cfSopenharmony_ci    def set_command_attr(self, attr):
66ca0551cfSopenharmony_ci        self._command_attr = attr
67ca0551cfSopenharmony_ci
68ca0551cfSopenharmony_ci    def set_command_ext_attr(self, attr):
69ca0551cfSopenharmony_ci        self._command_ext_attr = attr
70ca0551cfSopenharmony_ci
71ca0551cfSopenharmony_ci    def set_command_gen_langauge(self, langauge):
72ca0551cfSopenharmony_ci        self._gen_langauge = langauge
73ca0551cfSopenharmony_ci
74ca0551cfSopenharmony_ci    def set_output_dir(self, output_dir):
75ca0551cfSopenharmony_ci        self.output_dir = os.path.join(self.working_dir, output_dir)
76ca0551cfSopenharmony_ci
77ca0551cfSopenharmony_ci    def set_target_dir(self, target_dir):
78ca0551cfSopenharmony_ci       self.target_dir = os.path.join(self.working_dir, target_dir)
79ca0551cfSopenharmony_ci
80ca0551cfSopenharmony_ci    def set_system_attr(self, attr):
81ca0551cfSopenharmony_ci        self._system_attr = attr
82ca0551cfSopenharmony_ci
83ca0551cfSopenharmony_ci    def set_mode_attr(self, attr):
84ca0551cfSopenharmony_ci        self._mode_attr = attr
85ca0551cfSopenharmony_ci
86ca0551cfSopenharmony_ci    def set_package_path(self, package_path):
87ca0551cfSopenharmony_ci        self._package_path = package_path
88ca0551cfSopenharmony_ci
89ca0551cfSopenharmony_ci    def set_idl_dir(self, path):
90ca0551cfSopenharmony_ci        self.idl_dir = path
91ca0551cfSopenharmony_ci
92ca0551cfSopenharmony_ci    def set_not_use_default_add_idl_file(self, opt):
93ca0551cfSopenharmony_ci        self._not_use_default_add_idl_file = opt
94ca0551cfSopenharmony_ci
95ca0551cfSopenharmony_ci    def update_command(self):
96ca0551cfSopenharmony_ci        self.command = self._command_format.format(self._idl, self._system_attr, self._mode_attr,
97ca0551cfSopenharmony_ci                                                   self._command_attr, self._command_ext_attr,
98ca0551cfSopenharmony_ci                                                   self._gen_langauge, self._package_path, self.output_dir)
99ca0551cfSopenharmony_ci
100ca0551cfSopenharmony_ci    def set_output_path(self, output_path):
101ca0551cfSopenharmony_ci        self._output_path = output_path
102ca0551cfSopenharmony_ci
103ca0551cfSopenharmony_ci    def hash_command_update(self):
104ca0551cfSopenharmony_ci        hash_command = self._hash_command_format.format(self._idl, self._package_path,
105ca0551cfSopenharmony_ci                                                        self._command_attr, self._output_path)
106ca0551cfSopenharmony_ci        self.set_command(hash_command)
107ca0551cfSopenharmony_ci
108ca0551cfSopenharmony_ci    def dump_ast_command_update(self, use_tee=True):
109ca0551cfSopenharmony_ci        dump_ast_command = self._dump_ast_command_format.format(self._idl, self._package_path, self._command_attr,
110ca0551cfSopenharmony_ci                                                                self._command_ext_attr, self._output_path)
111ca0551cfSopenharmony_ci        if use_tee:
112ca0551cfSopenharmony_ci            dump_ast_command += f" | tee {self._output_path}"
113ca0551cfSopenharmony_ci        self.set_command(dump_ast_command)
114ca0551cfSopenharmony_ci
115ca0551cfSopenharmony_ci    def set_hash_param(self, package_path, command_attr):
116ca0551cfSopenharmony_ci        self.set_package_path(package_path)
117ca0551cfSopenharmony_ci        self.set_command_attr(f"-D {command_attr}")
118ca0551cfSopenharmony_ci        output_path = os.path.join(self.working_dir, "hash_out")
119ca0551cfSopenharmony_ci        if not os.path.exists(output_path):
120ca0551cfSopenharmony_ci            os.makedirs(output_path)
121ca0551cfSopenharmony_ci        self.set_output_path(os.path.join(output_path, "hash.txt"))
122ca0551cfSopenharmony_ci        self.set_output_dir(output_path)
123ca0551cfSopenharmony_ci        self.set_target_dir(os.path.join(self.working_dir, "hash_target"))
124ca0551cfSopenharmony_ci        self.set_not_use_default_add_idl_file(True)
125ca0551cfSopenharmony_ci        self.hash_command_update()
126ca0551cfSopenharmony_ci
127ca0551cfSopenharmony_ci    def set_dump_ast_check(self, if_check):
128ca0551cfSopenharmony_ci        self._dump_ast_check = if_check
129ca0551cfSopenharmony_ci
130ca0551cfSopenharmony_ci    def set_dump_ast_param(self, package_path, command_attr, use_tee=True):
131ca0551cfSopenharmony_ci        self.set_package_path(package_path)
132ca0551cfSopenharmony_ci        self.set_command_attr(f"-D {command_attr}")
133ca0551cfSopenharmony_ci        output_path = os.path.join(self.working_dir, "dump_ast_out")
134ca0551cfSopenharmony_ci        if not os.path.exists(output_path):
135ca0551cfSopenharmony_ci            os.makedirs(output_path)
136ca0551cfSopenharmony_ci        self.set_output_path(os.path.join(output_path, "dump.txt"))
137ca0551cfSopenharmony_ci        self.set_output_dir(output_path)
138ca0551cfSopenharmony_ci        self.set_target_dir(os.path.join(self.working_dir, "dump_ast_target"))
139ca0551cfSopenharmony_ci        self.set_not_use_default_add_idl_file(True)
140ca0551cfSopenharmony_ci        self.set_dump_ast_check(True)
141ca0551cfSopenharmony_ci        self.dump_ast_command_update(use_tee)
142ca0551cfSopenharmony_ci
143ca0551cfSopenharmony_ci    def set_command(self, command):
144ca0551cfSopenharmony_ci        self.command = command
145ca0551cfSopenharmony_ci
146ca0551cfSopenharmony_ci    def set_gen_c_env(self):
147ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-c")
148ca0551cfSopenharmony_ci        self.set_output_dir("c_out")
149ca0551cfSopenharmony_ci        self.set_target_dir("c_target")
150ca0551cfSopenharmony_ci        self.update_command()
151ca0551cfSopenharmony_ci
152ca0551cfSopenharmony_ci    def set_gen_cpp_env(self):
153ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-cpp")
154ca0551cfSopenharmony_ci        self.set_output_dir("cpp_out")
155ca0551cfSopenharmony_ci        self.set_target_dir("cpp_target")
156ca0551cfSopenharmony_ci        self.update_command()
157ca0551cfSopenharmony_ci
158ca0551cfSopenharmony_ci    def set_gen_java_env(self):
159ca0551cfSopenharmony_ci        self.set_command_gen_langauge("--gen-java")
160ca0551cfSopenharmony_ci        self.set_output_dir("java_out")
161ca0551cfSopenharmony_ci        self.set_target_dir("java_target")
162ca0551cfSopenharmony_ci        self.update_command()
163ca0551cfSopenharmony_ci
164ca0551cfSopenharmony_ci    def run(self):
165ca0551cfSopenharmony_ci        # please add test code here
166ca0551cfSopenharmony_ci        return False
167ca0551cfSopenharmony_ci
168ca0551cfSopenharmony_ci    def run_choose(self, choose):
169ca0551cfSopenharmony_ci        if choose:
170ca0551cfSopenharmony_ci            return self.run_success()
171ca0551cfSopenharmony_ci        return self.run_fail()
172ca0551cfSopenharmony_ci
173ca0551cfSopenharmony_ci    def run_success(self):
174ca0551cfSopenharmony_ci        if not self._not_use_default_add_idl_file:
175ca0551cfSopenharmony_ci            self.add_idl_files()
176ca0551cfSopenharmony_ci        status, ret = exec_command(self.command)
177ca0551cfSopenharmony_ci        if status != 0:
178ca0551cfSopenharmony_ci            print_failure(f"[ERROR] command:{self.command} run err")
179ca0551cfSopenharmony_ci            print_failure(f"[ERROR] {ret}")
180ca0551cfSopenharmony_ci            return False
181ca0551cfSopenharmony_ci        special_proc_func = None
182ca0551cfSopenharmony_ci        if self._dump_ast_check:
183ca0551cfSopenharmony_ci            special_proc_func = dump_ast_compare
184ca0551cfSopenharmony_ci        if compare_target_files(self.output_dir, self.target_dir, special_proc_func):
185ca0551cfSopenharmony_ci            return True
186ca0551cfSopenharmony_ci        return False
187ca0551cfSopenharmony_ci
188ca0551cfSopenharmony_ci    def run_fail(self):
189ca0551cfSopenharmony_ci        if not self._not_use_default_add_idl_file:
190ca0551cfSopenharmony_ci            self.add_idl_files()
191ca0551cfSopenharmony_ci        status, result = exec_command(self.command)
192ca0551cfSopenharmony_ci
193ca0551cfSopenharmony_ci        if status == 0:
194ca0551cfSopenharmony_ci            print_failure(f"[ERROR] ret({status}) run cmd: {self.command}")
195ca0551cfSopenharmony_ci            return False
196ca0551cfSopenharmony_ci
197ca0551cfSopenharmony_ci        expected_fail_output = ""
198ca0551cfSopenharmony_ci        with open(os.path.join(self.target_dir, "fail_output.txt"), 'r') as target_output:
199ca0551cfSopenharmony_ci            expected_fail_output = target_output.read()
200ca0551cfSopenharmony_ci
201ca0551cfSopenharmony_ci        if self._check_fail_ignore_line:
202ca0551cfSopenharmony_ci            ret = hdi_gen_fail_check_ignore_line(result, expected_fail_output)
203ca0551cfSopenharmony_ci            if not ret:
204ca0551cfSopenharmony_ci                print_failure(f"[ERROR] Expect ret: {expected_fail_output}")
205ca0551cfSopenharmony_ci                print_failure(f"[ERROR] Actual ret: {result}")
206ca0551cfSopenharmony_ci            return ret
207ca0551cfSopenharmony_ci
208ca0551cfSopenharmony_ci        if expected_fail_output != result:
209ca0551cfSopenharmony_ci            print_failure(f"[ERROR] Expect ret: {expected_fail_output}")
210ca0551cfSopenharmony_ci            print_failure(f"[ERROR] Actual ret: {result}")
211ca0551cfSopenharmony_ci            return False
212ca0551cfSopenharmony_ci        return True
213ca0551cfSopenharmony_ci
214ca0551cfSopenharmony_ci    def remove_output(self):
215ca0551cfSopenharmony_ci        exec_command("rm -rf {}".format(self.output_dir))
216ca0551cfSopenharmony_ci        return True
217ca0551cfSopenharmony_ci
218ca0551cfSopenharmony_ci    def add_idl_files(self):
219ca0551cfSopenharmony_ci        idl_list = get_all_idl_files(self.idl_dir)
220ca0551cfSopenharmony_ci        for idl in idl_list:
221ca0551cfSopenharmony_ci            self.command = "".join((self.command, " -c {}".format(idl)))
222ca0551cfSopenharmony_ci
223ca0551cfSopenharmony_ci    def test(self):
224ca0551cfSopenharmony_ci        print_success("[ RUN       ] {}".format(self.name))
225ca0551cfSopenharmony_ci        start_time = get_time_stamp()
226ca0551cfSopenharmony_ci        result = self.run()
227ca0551cfSopenharmony_ci        end_time = get_time_stamp()
228ca0551cfSopenharmony_ci
229ca0551cfSopenharmony_ci        if result:
230ca0551cfSopenharmony_ci            print_success("[        OK ] {} ({}ms)".format(self.name, end_time - start_time))
231ca0551cfSopenharmony_ci        else:
232ca0551cfSopenharmony_ci            print_failure("[    FAILED ] {} ({}ms)".format(self.name, end_time - start_time))
233ca0551cfSopenharmony_ci        return result
234