• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""Copyright (C) 2022 The Android Open Source Project
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7     http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14"""
15
16load("@bazel_skylib//lib:paths.bzl", "paths")
17load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
18load("//build/bazel/rules:hidl_file_utils.bzl", "INTERFACE_HEADER_PREFIXES", "TYPE_HEADER_PREFIXES")
19load("//build/bazel/rules/hidl:hidl_interface.bzl", "INTERFACE_SUFFIX")
20load("//build/bazel/rules/hidl:hidl_library.bzl", "hidl_library")
21load(":cc_hidl_library.bzl", "CC_HEADER_SUFFIX", "cc_hidl_library")
22
23HIDL_GEN = "prebuilts/build-tools/linux-x86/bin/hidl-gen"
24
25SRC_TYPE_NAME_1 = "types_1.hal"
26GEN_TYPE_NAME_1 = "types_1.h"
27SRC_INTERFACE_NAME_1 = "IInterface_1.hal"
28GEN_INTERFACE_NAME_1 = "Interface_1.h"
29ROOT_1 = "android.hardware"
30ROOT_INTERFACE_FILE_LABEL_1 = "//hardware/interfaces:current.txt"
31ROOT_INTERFACE_FILE_1 = "hardware/interfaces/current.txt"
32INTERFACE_PACKAGE_NAME_1 = "android.hardware.int1"
33ROOT_ARGUMENT_1 = "android.hardware:hardware/interfaces"
34
35SRC_TYPE_NAME_2 = "types_2.hal"
36SRC_INTERFACE_NAME_2 = "IInterface_2.hal"
37ROOT_2 = "android.hidl"
38ROOT_INTERFACE_FILE_LABEL_2 = "//system/libhidl/transport:current.txt"
39ROOT_INTERFACE_FILE_2 = "system/libhidl/transport/current.txt"
40ROOT_ARGUMENT_2 = "android.hidl:system/libhidl/transport"
41INTERFACE_PACKAGE_NAME_2 = "android.hidl.int2"
42
43INTERFACE_PACKAGE_NAME_CORE = "android.hidl.base"
44
45INTERFACE_VERSION_1_0 = "1.0"
46INTERFACE_VERSION_1_1 = "1.1"
47
48def _cc_code_gen_test_impl(ctx):
49    env = analysistest.begin(ctx)
50    actions = analysistest.target_actions(env)
51    package_root = paths.dirname(ctx.build_file_path)
52    header_gen_actions = [a for a in actions if a.mnemonic == "HidlGenCcHeader"]
53    asserts.true(
54        env,
55        len(header_gen_actions) == 1,
56        "Cc header gen action not found: %s" % actions,
57    )
58
59    header_gen_action = header_gen_actions[0]
60
61    asserts.equals(
62        env,
63        expected = sorted([
64            paths.join(package_root, SRC_TYPE_NAME_1),
65            paths.join(package_root, SRC_INTERFACE_NAME_1),
66            paths.join(package_root, SRC_TYPE_NAME_2),
67            paths.join(package_root, SRC_INTERFACE_NAME_2),
68            ROOT_INTERFACE_FILE_1,
69            ROOT_INTERFACE_FILE_2,
70            paths.join(HIDL_GEN),
71        ]),
72        actual = sorted([
73            file.short_path
74            for file in header_gen_action.inputs.to_list()
75        ]),
76    )
77
78    path = paths.join(package_root, INTERFACE_PACKAGE_NAME_1.replace(".", "/"), INTERFACE_VERSION_1_0)
79    asserts.equals(
80        env,
81        expected = sorted(
82            [
83                paths.join(path, prefix + GEN_TYPE_NAME_1)
84                for prefix in TYPE_HEADER_PREFIXES
85            ] +
86            [
87                paths.join(path, prefix + GEN_INTERFACE_NAME_1)
88                for prefix in INTERFACE_HEADER_PREFIXES
89            ],
90        ),
91        actual = sorted([
92            file.short_path
93            for file in header_gen_action.outputs.to_list()
94        ]),
95    )
96
97    cmd = header_gen_action.argv
98    asserts.true(
99        env,
100        HIDL_GEN == cmd[0],
101        "hidl-gen is not called: %s" % cmd,
102    )
103
104    asserts.true(
105        env,
106        "-R" in cmd,
107        "Calling hidl-gen without -R: %s" % cmd,
108    )
109
110    index = cmd.index("-p")
111    asserts.true(
112        env,
113        index > 0,
114        "Calling hidl-gen without -p: %s" % cmd,
115    )
116
117    asserts.true(
118        env,
119        cmd[index + 1] == ".",
120        ". needs to follow -p: %s" % cmd,
121    )
122
123    index = cmd.index("-o")
124    asserts.true(
125        env,
126        index > 0,
127        "Calling hidl-gen without -o: %s" % cmd,
128    )
129
130    asserts.true(
131        env,
132        cmd[index + 1].endswith(package_root),
133        "Incorrect output path: %s" % cmd,
134    )
135
136    index = cmd.index("-L")
137    asserts.true(
138        env,
139        index > 0,
140        "Calling hidl-gen without -L: %s" % cmd,
141    )
142
143    asserts.true(
144        env,
145        cmd[index + 1] == "c++-headers",
146        "Incorrect language: %s" % cmd,
147    )
148
149    roots = []
150    cmd_len = len(cmd)
151    for i in range(cmd_len):
152        if cmd[i] == "-r":
153            roots.append(cmd[i + 1])
154
155    asserts.equals(
156        env,
157        expected = sorted([
158            ROOT_ARGUMENT_1,
159            ROOT_ARGUMENT_2,
160        ]),
161        actual = sorted(roots),
162    )
163
164    asserts.true(
165        env,
166        cmd[cmd_len - 1] == INTERFACE_PACKAGE_NAME_1 + "@" + INTERFACE_VERSION_1_0,
167        "The last arg should be the FQ name of the interface: %s" % cmd,
168    )
169
170    return analysistest.end(env)
171
172cc_code_gen_test = analysistest.make(
173    _cc_code_gen_test_impl,
174)
175
176def _test_cc_code_gen():
177    test_name = "cc_code_gen_test"
178    cc_name = INTERFACE_PACKAGE_NAME_1 + "@" + INTERFACE_VERSION_1_0
179    interface_name = cc_name + INTERFACE_SUFFIX
180    cc_name_dep = INTERFACE_PACKAGE_NAME_2 + "@" + INTERFACE_VERSION_1_0
181    interface_name_dep = cc_name_dep + INTERFACE_SUFFIX
182
183    hidl_library(
184        name = interface_name_dep,
185        root = ROOT_2,
186        root_interface_file = ROOT_INTERFACE_FILE_LABEL_2,
187        fq_name = cc_name_dep,
188        srcs = [
189            SRC_TYPE_NAME_2,
190            SRC_INTERFACE_NAME_2,
191        ],
192        tags = ["manual"],
193    )
194
195    cc_hidl_library(
196        name = cc_name_dep,
197        interface = interface_name_dep,
198        tags = ["manual"],
199    )
200
201    hidl_library(
202        name = interface_name,
203        deps = [interface_name_dep],
204        root = ROOT_1,
205        root_interface_file = ROOT_INTERFACE_FILE_LABEL_1,
206        fq_name = cc_name,
207        srcs = [
208            SRC_TYPE_NAME_1,
209            SRC_INTERFACE_NAME_1,
210        ],
211        tags = ["manual"],
212    )
213
214    cc_hidl_library(
215        name = cc_name,
216        interface = interface_name,
217        dynamic_deps = [cc_name_dep],
218        tags = ["manual"],
219    )
220
221    cc_code_gen_test(
222        name = test_name,
223        target_under_test = cc_name + CC_HEADER_SUFFIX,
224    )
225
226    return test_name
227
228def _cc_interface_dep_test_impl(ctx):
229    env = analysistest.begin(ctx)
230    target_under_test = analysistest.target_under_test(env)
231    dynamic_deps = target_under_test[CcSharedLibraryInfo].dynamic_deps
232
233    dep_name = INTERFACE_PACKAGE_NAME_CORE + "@" + INTERFACE_VERSION_1_1
234    package_root = paths.dirname(ctx.build_file_path)
235
236    asserts.false(
237        env,
238        _find_dep(package_root, dep_name, dynamic_deps),
239        "Core package in the dependencies: %s %s" % (dep_name, dynamic_deps),
240    )
241
242    dep_name = INTERFACE_PACKAGE_NAME_2 + "@" + INTERFACE_VERSION_1_1
243    asserts.true(
244        env,
245        _find_dep(package_root, dep_name, dynamic_deps),
246        "Missing valid dependency: %s %s" % (dep_name, dynamic_deps),
247    )
248
249    return analysistest.end(env)
250
251def _find_dep(package_root, name, deps):
252    full_name = "@//" + package_root + ":" + name
253    for lists in deps.to_list():
254        for dep in lists[0]:
255            if dep.startswith(full_name):
256                return True
257
258    return False
259
260cc_interface_dep_test = analysistest.make(
261    _cc_interface_dep_test_impl,
262)
263
264def _test_cc_interface_dep():
265    test_name = "cc_interface_dep_test"
266    cc_name = INTERFACE_PACKAGE_NAME_1 + "@" + INTERFACE_VERSION_1_1
267    interface_name = cc_name + INTERFACE_SUFFIX
268    cc_name_dep = INTERFACE_PACKAGE_NAME_2 + "@" + INTERFACE_VERSION_1_1
269    interface_name_dep = cc_name_dep + INTERFACE_SUFFIX
270    cc_name_core = INTERFACE_PACKAGE_NAME_CORE + "@" + INTERFACE_VERSION_1_1
271    interface_name_core = cc_name_core + INTERFACE_SUFFIX
272
273    hidl_library(
274        name = interface_name_dep,
275        root = ROOT_2,
276        root_interface_file = ROOT_INTERFACE_FILE_LABEL_2,
277        fq_name = cc_name_dep,
278        srcs = [
279            SRC_TYPE_NAME_2,
280            SRC_INTERFACE_NAME_2,
281        ],
282        tags = ["manual"],
283    )
284
285    cc_hidl_library(
286        name = cc_name_dep,
287        interface = interface_name_dep,
288        tags = ["manual"],
289    )
290
291    hidl_library(
292        name = interface_name_core,
293        root = ROOT_2,
294        root_interface_file = ROOT_INTERFACE_FILE_LABEL_2,
295        fq_name = cc_name_core,
296        srcs = [
297            SRC_TYPE_NAME_2,
298            SRC_INTERFACE_NAME_2,
299        ],
300        tags = ["manual"],
301    )
302
303    cc_hidl_library(
304        name = cc_name_core,
305        interface = interface_name_core,
306        tags = ["manual"],
307    )
308
309    hidl_library(
310        name = interface_name,
311        deps = [interface_name_dep, interface_name_core],
312        root = ROOT_1,
313        root_interface_file = ROOT_INTERFACE_FILE_LABEL_1,
314        fq_name = cc_name,
315        srcs = [
316            SRC_TYPE_NAME_1,
317            SRC_INTERFACE_NAME_1,
318        ],
319        tags = ["manual"],
320    )
321
322    cc_hidl_library(
323        name = cc_name,
324        interface = interface_name,
325        dynamic_deps = [cc_name_dep, cc_name_core],
326        tags = ["manual"],
327    )
328
329    cc_interface_dep_test(
330        name = test_name,
331        target_under_test = cc_name,
332    )
333
334    return test_name
335
336def cc_hidl_library_test_suite(name):
337    native.test_suite(
338        name = name,
339        tests = [
340            _test_cc_code_gen(),
341            _test_cc_interface_dep(),
342        ],
343    )
344