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:unittest.bzl", "analysistest", "unittest", skylib_asserts = "asserts")
16load("//build/bazel/rules/test_common:asserts.bzl", roboleaf_asserts = "asserts")
17load("//build/bazel/rules/test_common:rules.bzl", "target_under_test_exist_test")
18load(":cc_binary.bzl", "cc_binary")
19load(":cc_library_common.bzl", "CcAndroidMkInfo", "is_external_directory")
20load(":cc_library_shared.bzl", "cc_library_shared")
21load(":cc_library_static.bzl", "cc_library_static")
22load(":cc_prebuilt_library_shared.bzl", "cc_prebuilt_library_shared")
23
24asserts = skylib_asserts + roboleaf_asserts
25
26def _is_external_directory_test(ctx):
27    env = unittest.begin(ctx)
28
29    actual = is_external_directory(ctx.attr.path)
30
31    asserts.equals(env, ctx.attr.expected_value, actual, "expected {path}, to be {external}".format(
32        path = ctx.attr.path,
33        external = "external" if ctx.attr.expected_value else "non-external",
34    ))
35
36    return unittest.end(env)
37
38is_external_directory_test = unittest.make(
39    _is_external_directory_test,
40    attrs = {
41        "path": attr.string(),
42        "expected_value": attr.bool(),
43    },
44)
45
46def _is_external_directory_tests():
47    test_cases = {
48        "non_external": struct(
49            path = "path/to/package",
50            expected_value = False,
51        ),
52        "external": struct(
53            path = "external/path/to/package",
54            expected_value = True,
55        ),
56        "hardware": struct(
57            path = "hardware/path/to/package",
58            expected_value = True,
59        ),
60        "only_hardware": struct(
61            path = "hardware",
62            expected_value = True,
63        ),
64        "hardware_google": struct(
65            path = "hardware/google/path/to/package",
66            expected_value = False,
67        ),
68        "hardware_interfaces": struct(
69            path = "hardware/interfaces/path/to/package",
70            expected_value = False,
71        ),
72        "hardware_ril": struct(
73            path = "hardware/ril/path/to/package",
74            expected_value = False,
75        ),
76        "hardware_libhardware_dir": struct(
77            path = "hardware/libhardware/path/to/package",
78            expected_value = False,
79        ),
80        "hardware_libhardware_partial": struct(
81            path = "hardware/libhardware_legacy/path/to/package",
82            expected_value = False,
83        ),
84        "vendor": struct(
85            path = "vendor/path/to/package",
86            expected_value = True,
87        ),
88        "only_vendor": struct(
89            path = "vendor",
90            expected_value = True,
91        ),
92        "vendor_google": struct(
93            path = "vendor/google/path/to/package",
94            expected_value = False,
95        ),
96        "vendor_google_with_prefix": struct(
97            path = "vendor/pre_google/path/to/package",
98            expected_value = False,
99        ),
100        "vendor_google_with_postfix": struct(
101            path = "vendor/google_post/path/to/package",
102            expected_value = False,
103        ),
104    }
105
106    for name, test_case in test_cases.items():
107        is_external_directory_test(
108            name = name,
109            path = test_case.path,
110            expected_value = test_case.expected_value,
111        )
112    return test_cases.keys()
113
114def _target_provides_androidmk_info_test_impl(ctx):
115    env = analysistest.begin(ctx)
116
117    target_under_test = analysistest.target_under_test(env)
118    mkinfo = target_under_test[CcAndroidMkInfo]
119    asserts.list_equals(
120        env,
121        ctx.attr.expected_static_libs,
122        mkinfo.local_static_libs,
123        "expected static_libs to be %s, but got %s" % (
124            ctx.attr.expected_static_libs,
125            mkinfo.local_static_libs,
126        ),
127    )
128    asserts.list_equals(
129        env,
130        ctx.attr.expected_whole_static_libs,
131        mkinfo.local_whole_static_libs,
132        "expected whole_static_libs to be %s, but got %s" % (
133            ctx.attr.expected_whole_static_libs,
134            mkinfo.local_whole_static_libs,
135        ),
136    )
137    asserts.list_equals(
138        env,
139        ctx.attr.expected_shared_libs,
140        mkinfo.local_shared_libs,
141        "expected shared_libs to be %s, but got %s" % (
142            ctx.attr.expected_shared_libs,
143            mkinfo.local_shared_libs,
144        ),
145    )
146
147    return analysistest.end(env)
148
149target_provides_androidmk_info_test = analysistest.make(
150    _target_provides_androidmk_info_test_impl,
151    attrs = {
152        "expected_static_libs": attr.string_list(),
153        "expected_whole_static_libs": attr.string_list(),
154        "expected_shared_libs": attr.string_list(),
155    },
156)
157
158# Same as target_provides_androidmk_info_test, but builds sdk variant of cc_libraries
159target_sdk_variant_provides_androidmk_info_test = analysistest.make(
160    _target_provides_androidmk_info_test_impl,
161    attrs = {
162        "expected_static_libs": attr.string_list(),
163        "expected_whole_static_libs": attr.string_list(),
164        "expected_shared_libs": attr.string_list(),
165    },
166    config_settings = {
167        "@//build/bazel/rules/apex:api_domain": "unbundled_app",
168    },
169)
170
171def _test_cc_prebuilt_library_shared_is_valid_dynamic_dep():
172    name = "cc_prebuilt_library_shared_is_valid_dynamic_dep"
173    prebuilt_name = name + "_prebuilt"
174    static_name = name + "_static"
175    shared_name = name + "_shared"
176    binary_name = name + "_binary"
177    static_test_name = static_name + "_test"
178    shared_test_name = shared_name + "_test"
179    binary_test_name = binary_name + "_test"
180
181    cc_prebuilt_library_shared(
182        name = prebuilt_name,
183        shared_library = "a.so",
184        tags = ["manual"],
185    )
186    cc_library_static(
187        name = static_name,
188        srcs = ["a.cpp"],
189        dynamic_deps = [prebuilt_name],
190        tags = ["manual"],
191    )
192    cc_library_shared(
193        name = shared_name,
194        srcs = ["a.cpp"],
195        dynamic_deps = [prebuilt_name],
196        tags = ["manual"],
197    )
198    cc_binary(
199        name = binary_name,
200        srcs = ["a.cpp"],
201        dynamic_deps = [prebuilt_name],
202        tags = ["manual"],
203    )
204
205    target_under_test_exist_test(
206        name = static_test_name,
207        target_under_test = static_name,
208    )
209    target_under_test_exist_test(
210        name = shared_test_name,
211        target_under_test = shared_name,
212    )
213    target_under_test_exist_test(
214        name = binary_test_name,
215        target_under_test = binary_name,
216    )
217
218    return [
219        static_test_name,
220        shared_test_name,
221        binary_test_name,
222    ]
223
224def cc_library_common_test_suites(name):
225    native.test_suite(
226        name = name,
227        tests = (
228            _is_external_directory_tests() +
229            _test_cc_prebuilt_library_shared_is_valid_dynamic_dep()
230        ),
231    )
232