1# Copyright (C) 2022 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("@bazel_skylib//lib:new_sets.bzl", "sets")
16load("@bazel_skylib//lib:paths.bzl", "paths")
17load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
18load("//build/bazel/rules/aidl:aidl_library.bzl", "aidl_library")
19load("//build/bazel/rules/cc:cc_aidl_library.bzl", "cc_aidl_library")
20load("//build/bazel/rules/test_common:flags.bzl", "action_flags_present_only_for_mnemonic_test")
21
22aidl_library_label_name = "foo_aidl_library"
23aidl_files = [
24    "a/b/A.aidl",
25    "a/b/B.aidl",
26]
27
28def _cc_aidl_code_gen_test_impl(ctx):
29    env = analysistest.begin(ctx)
30    actions = analysistest.target_actions(env)
31    asserts.true(
32        env,
33        len(actions) == 1,
34        "expected to have one action per aidl_library target",
35    )
36    cc_aidl_code_gen_target = analysistest.target_under_test(env)
37    action = actions[0]
38    argv = action.argv
39
40    # Check inputs are correctly added to command
41    aidl_input_path_template = paths.join(
42        ctx.genfiles_dir.path,
43        ctx.label.package,
44        "_virtual_imports",
45        aidl_library_label_name,
46    ) + "/{}"
47    expected_inputs = [
48        aidl_input_path_template.format(file)
49        for file in aidl_files
50    ]
51    for expected_input in expected_inputs:
52        asserts.true(
53            env,
54            expected_input in argv,
55            "expect {} to be passed to aidl command".format(expected_input),
56        )
57
58    # Check generated outputs
59    output_path = paths.join(
60        ctx.genfiles_dir.path,
61        ctx.label.package,
62        cc_aidl_code_gen_target.label.name,
63    )
64    expected_outputs = []
65    expected_outputs.extend(
66        [
67            paths.join(output_path, "a/b/BpA.h"),
68            paths.join(output_path, "a/b/BnA.h"),
69            paths.join(output_path, "a/b/A.h"),
70            paths.join(output_path, "a/b/A.cpp"),
71            paths.join(output_path, "a/b/BpB.h"),
72            paths.join(output_path, "a/b/BnB.h"),
73            paths.join(output_path, "a/b/B.h"),
74            paths.join(output_path, "a/b/B.cpp"),
75        ],
76    )
77
78    asserts.set_equals(
79        env,
80        sets.make(expected_outputs),
81        sets.make([output.path for output in action.outputs.to_list()]),
82    )
83
84    # Check the output path is correctly added to includes in CcInfo.compilation_context
85    asserts.true(
86        env,
87        output_path in cc_aidl_code_gen_target[CcInfo].compilation_context.includes.to_list(),
88        "output path is added to CcInfo.compilation_context.includes",
89    )
90
91    return analysistest.end(env)
92
93cc_aidl_code_gen_test = analysistest.make(
94    _cc_aidl_code_gen_test_impl,
95)
96
97def _cc_aidl_code_gen_test():
98    name = "foo"
99    aidl_code_gen_name = name + "_aidl_code_gen"
100    code_gen_test_name = aidl_code_gen_name + "_test"
101
102    aidl_library(
103        name = aidl_library_label_name,
104        srcs = aidl_files,
105        tags = ["manual"],
106    )
107    cc_aidl_library(
108        name = name,
109        deps = [":foo_aidl_library"],
110        tags = ["manual"],
111    )
112    cc_aidl_code_gen_test(
113        name = code_gen_test_name,
114        target_under_test = aidl_code_gen_name,
115    )
116
117    action_flags_present_test_name = name + "_test_action_flags_present"
118    action_flags_present_only_for_mnemonic_test(
119        name = action_flags_present_test_name,
120        target_under_test = name + "_cpp",
121        mnemonics = ["CppCompile"],
122        expected_flags = [
123            "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES",
124        ],
125    )
126
127    return [
128        code_gen_test_name,
129        action_flags_present_test_name,
130    ]
131
132def _cc_aidl_hash_notfrozen():
133    aidl_library_name = "cc_aidl_hash_notfrozen"
134    cc_aidl_library_name = aidl_library_name + "cc_aidl_library"
135    aidl_code_gen_name = cc_aidl_library_name + "_aidl_code_gen"
136    test_name = aidl_code_gen_name + "_test"
137
138    aidl_library(
139        name = aidl_library_name,
140        srcs = aidl_files,
141        tags = ["manual"],
142    )
143    cc_aidl_library(
144        name = cc_aidl_library_name,
145        deps = [aidl_library_name],
146        tags = ["manual"],
147    )
148    action_flags_present_only_for_mnemonic_test(
149        name = test_name,
150        target_under_test = aidl_code_gen_name,
151        mnemonics = ["CcAidlCodeGen"],
152        expected_flags = ["--hash=notfrozen"],
153    )
154
155    return test_name
156
157def _cc_aidl_hash_flag_with_hash_file():
158    aidl_library_name = "cc_aidl_hash_flag_with_hash_file"
159    cc_aidl_library_name = aidl_library_name + "cc_aidl_library"
160    aidl_code_gen_name = cc_aidl_library_name + "_aidl_code_gen"
161    test_name = aidl_code_gen_name + "_test"
162
163    aidl_library(
164        name = aidl_library_name,
165        srcs = aidl_files,
166        hash_file = "cc_aidl_hash_flag_with_hash_file/.hash",
167        tags = ["manual"],
168    )
169    cc_aidl_library(
170        name = cc_aidl_library_name,
171        deps = [aidl_library_name],
172        tags = ["manual"],
173    )
174    action_flags_present_only_for_mnemonic_test(
175        name = test_name,
176        target_under_test = aidl_code_gen_name,
177        mnemonics = ["CcAidlCodeGen"],
178        expected_flags = [
179            "--hash=$(tail -1 <source file build/bazel/rules/cc/cc_aidl_hash_flag_with_hash_file/.hash>)",
180        ],
181    )
182
183    return test_name
184
185def cc_aidl_library_test_suite(name):
186    native.test_suite(
187        name = name,
188        tests = [
189            _cc_aidl_hash_notfrozen(),
190            _cc_aidl_hash_flag_with_hash_file(),
191        ] + _cc_aidl_code_gen_test(),
192    )
193