1"""Copyright (C) 2023 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:sets.bzl", "sets")
18load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
19load(":ndk_headers.bzl", "ndk_headers")
20
21def _ndk_headers_test_impl(ctx):
22    env = analysistest.begin(ctx)
23    target_under_test = analysistest.target_under_test(env)
24    target_bin_dir_path = analysistest.target_bin_dir_path(env)
25
26    # check that versioner was run for versioned NDK headers
27    if ctx.attr.expected_run_versioner:
28        version_action = [a for a in analysistest.target_actions(env) if a.mnemonic == "VersionBionicHeaders"]
29        asserts.equals(
30            env,
31            len(version_action),
32            1,
33            "Expected versioner to run once",
34        )
35
36    asserts.set_equals(
37        env,
38        expected = sets.make([
39            paths.join(ctx.attr.expected_isystem, file)
40            for file in ctx.attr.expected_hdrs
41        ]),
42        actual = sets.make([
43            file.short_path
44            for file in target_under_test[DefaultInfo].files.to_list()
45        ]),
46    )
47
48    compilation_context = target_under_test[CcInfo].compilation_context
49
50    # check -I
51    asserts.equals(
52        env,
53        [],
54        compilation_context.includes.to_list(),
55        "ndk headers should be added as -isystem and not -I",
56    )
57
58    # check -isystem
59    asserts.equals(
60        env,
61        [
62            paths.join(
63                target_bin_dir_path,
64                ctx.attr.expected_isystem,
65            ),
66            # check for the NDK triple
67            paths.join(
68                target_bin_dir_path,
69                ctx.attr.expected_isystem,
70                "arm-linux-androideabi",
71            ),
72        ],
73        compilation_context.system_includes.to_list(),
74        "CcInfo returned by ndk headers does not have the correct -isystem",
75    )
76
77    return analysistest.end(env)
78
79ndk_headers_test = analysistest.make(
80    _ndk_headers_test_impl,
81    attrs = {
82        "expected_hdrs": attr.string_list(),
83        "expected_isystem": attr.string(doc = "expected dir relative to bin dir that will be provided as -isystem to rdeps"),
84        "expected_run_versioner": attr.bool(default = False),
85    },
86    # Pin the test to a consistent arch
87    config_settings = {
88        "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm_for_testing",
89    },
90)
91
92def _test_ndk_headers_simple():
93    test_name = "ndk_headers_simple"
94    target_under_test_name = test_name + "_target"
95
96    ndk_headers(
97        name = target_under_test_name,
98        hdrs = ["a/aa.h", "a/ab.h"],
99        tags = ["manual"],
100    )
101
102    ndk_headers_test(
103        name = test_name,
104        target_under_test = target_under_test_name,
105        expected_hdrs = ["a/aa.h", "a/ab.h"],
106        expected_isystem = "build/bazel/rules/cc/" + target_under_test_name,
107    )
108
109    return test_name
110
111def _test_ndk_headers_non_empty_strip_import():
112    test_name = "ndk_headers_non_empty_strip_import"
113    target_under_test_name = test_name + "_target"
114
115    ndk_headers(
116        name = target_under_test_name,
117        strip_import_prefix = "a",
118        hdrs = ["a/aa.h", "a/ab.h"],
119        tags = ["manual"],
120    )
121
122    ndk_headers_test(
123        name = test_name,
124        target_under_test = target_under_test_name,
125        expected_hdrs = ["aa.h", "ab.h"],
126        expected_isystem = "build/bazel/rules/cc/" + target_under_test_name,
127    )
128
129    return test_name
130
131def _test_ndk_headers_non_empty_import():
132    test_name = "ndk_headers_non_empty_import"
133    target_under_test_name = test_name + "_target"
134
135    ndk_headers(
136        name = target_under_test_name,
137        import_prefix = "b",
138        hdrs = ["a/aa.h", "a/ab.h"],
139        tags = ["manual"],
140    )
141
142    ndk_headers_test(
143        name = test_name,
144        target_under_test = target_under_test_name,
145        expected_hdrs = ["b/a/aa.h", "b/a/ab.h"],
146        expected_isystem = "build/bazel/rules/cc/" + target_under_test_name,
147    )
148
149    return test_name
150
151def _test_ndk_headers_non_empty_strip_import_and_import():
152    test_name = "ndk_headers_non_empty_strip_import_and_import"
153    target_under_test_name = test_name + "_target"
154
155    ndk_headers(
156        name = target_under_test_name,
157        strip_import_prefix = "a",
158        import_prefix = "b",
159        hdrs = ["a/aa.h", "a/ab.h"],
160        tags = ["manual"],
161    )
162
163    ndk_headers_test(
164        name = test_name,
165        target_under_test = target_under_test_name,
166        expected_hdrs = ["b/aa.h", "b/ab.h"],
167        expected_isystem = "build/bazel/rules/cc/" + target_under_test_name,
168    )
169
170    return test_name
171
172def _test_versioned_ndk_headers_non_empty_strip_import_and_import():
173    test_name = "versioned_ndk_headers_non_empty_strip_import_and_import"
174    target_under_test_name = test_name + "_target"
175
176    ndk_headers(
177        name = target_under_test_name,
178        strip_import_prefix = "a",
179        import_prefix = "b",
180        hdrs = ["a/aa.h", "a/ab.h"],
181        run_versioner = True,
182        tags = ["manual"],
183    )
184
185    ndk_headers_test(
186        name = test_name,
187        target_under_test = target_under_test_name,
188        expected_hdrs = ["b/aa.h", "b/ab.h"],
189        expected_isystem = "build/bazel/rules/cc/" + target_under_test_name + ".versioned",
190        expected_run_versioner = True,
191    )
192
193    return test_name
194
195def ndk_headers_test_suite(name):
196    native.test_suite(
197        name = name,
198        tests = [
199            _test_ndk_headers_simple(),
200            _test_ndk_headers_non_empty_strip_import(),
201            _test_ndk_headers_non_empty_import(),
202            _test_ndk_headers_non_empty_strip_import_and_import(),
203            _test_versioned_ndk_headers_non_empty_strip_import_and_import(),
204        ],
205    )
206