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(":cc_api_contribution.bzl", "CcApiContributionInfo", "CcApiHeaderInfo", "CcApiHeaderInfoList", "cc_api_contribution", "cc_api_headers", "cc_api_library_headers") 19 20def _empty_include_dir_test_impl(ctx): 21 env = analysistest.begin(ctx) 22 target_under_test = analysistest.target_under_test(env) 23 asserts.equals(env, paths.dirname(ctx.build_file_path), target_under_test[CcApiHeaderInfo].root) 24 return analysistest.end(env) 25 26empty_include_dir_test = analysistest.make(_empty_include_dir_test_impl) 27 28def _empty_include_dir_test(): 29 test_name = "empty_include_dir_test" 30 subject_name = test_name + "_subject" 31 cc_api_headers( 32 name = subject_name, 33 hdrs = ["hdr.h"], 34 tags = ["manual"], 35 ) 36 empty_include_dir_test( 37 name = test_name, 38 target_under_test = subject_name, 39 ) 40 return test_name 41 42def _nonempty_include_dir_test_impl(ctx): 43 env = analysistest.begin(ctx) 44 target_under_test = analysistest.target_under_test(env) 45 expected_root = paths.join(paths.dirname(ctx.build_file_path), ctx.attr.expected_include_dir) 46 asserts.equals(env, expected_root, target_under_test[CcApiHeaderInfo].root) 47 return analysistest.end(env) 48 49nonempty_include_dir_test = analysistest.make( 50 impl = _nonempty_include_dir_test_impl, 51 attrs = { 52 "expected_include_dir": attr.string(), 53 }, 54) 55 56def _nonempty_include_dir_test(): 57 test_name = "nonempty_include_dir_test" 58 subject_name = test_name + "_subject" 59 include_dir = "my/include" 60 cc_api_headers( 61 name = subject_name, 62 include_dir = include_dir, 63 hdrs = ["my/include/hdr.h"], 64 tags = ["manual"], 65 ) 66 nonempty_include_dir_test( 67 name = test_name, 68 target_under_test = subject_name, 69 expected_include_dir = include_dir, 70 ) 71 return test_name 72 73def _api_library_headers_test_impl(ctx): 74 env = analysistest.begin(ctx) 75 target_under_test = analysistest.target_under_test(env) 76 asserts.true(env, CcApiHeaderInfoList in target_under_test) 77 headers_list = target_under_test[CcApiHeaderInfoList].headers_list 78 actual_includes = sorted([headers.root for headers in headers_list if not headers.system]) 79 actual_system_includes = sorted([headers.root for headers in headers_list if headers.system]) 80 asserts.equals(env, ctx.attr.expected_includes, actual_includes) 81 asserts.equals(env, ctx.attr.expected_system_includes, actual_system_includes) 82 return analysistest.end(env) 83 84api_library_headers_test = analysistest.make( 85 impl = _api_library_headers_test_impl, 86 attrs = { 87 "expected_includes": attr.string_list(), 88 "expected_system_includes": attr.string_list(), 89 }, 90) 91 92def _api_library_headers_test(): 93 test_name = "api_library_headers_test" 94 subject_name = test_name + "_subject" 95 cc_api_library_headers( 96 name = subject_name, 97 hdrs = [], 98 export_includes = ["include1", "include2"], 99 export_system_includes = ["system_include1"], 100 deps = [":other_api_library_headers", "other_api_headers"], 101 tags = ["manual"], 102 ) 103 cc_api_library_headers( 104 name = "other_api_library_headers", 105 hdrs = [], 106 export_includes = ["otherinclude1"], 107 tags = ["manual"], 108 ) 109 cc_api_headers( 110 name = "other_api_headers", 111 hdrs = [], 112 include_dir = "otherinclude2", 113 tags = ["manual"], 114 ) 115 api_library_headers_test( 116 name = test_name, 117 target_under_test = subject_name, 118 expected_includes = ["build/bazel/rules/apis/include1", "build/bazel/rules/apis/include2", "build/bazel/rules/apis/otherinclude1", "build/bazel/rules/apis/otherinclude2"], 119 expected_system_includes = ["build/bazel/rules/apis/system_include1"], 120 ) 121 return test_name 122 123def _api_path_is_relative_to_workspace_root_test_impl(ctx): 124 env = analysistest.begin(ctx) 125 target_under_test = analysistest.target_under_test(env) 126 expected_path = paths.join(paths.dirname(ctx.build_file_path), ctx.attr.expected_symbolfile) 127 asserts.equals(env, expected_path, target_under_test[CcApiContributionInfo].api) 128 return analysistest.end(env) 129 130api_path_is_relative_to_workspace_root_test = analysistest.make( 131 impl = _api_path_is_relative_to_workspace_root_test_impl, 132 attrs = { 133 "expected_symbolfile": attr.string(), 134 }, 135) 136 137def _api_path_is_relative_to_workspace_root_test(): 138 test_name = "api_path_is_relative_workspace_root" 139 subject_name = test_name + "_subject" 140 symbolfile = "libfoo.map.txt" 141 cc_api_contribution( 142 name = subject_name, 143 api = symbolfile, 144 tags = ["manual"], 145 ) 146 api_path_is_relative_to_workspace_root_test( 147 name = test_name, 148 target_under_test = subject_name, 149 expected_symbolfile = symbolfile, 150 ) 151 return test_name 152 153def _empty_library_name_gets_label_name_impl(ctx): 154 env = analysistest.begin(ctx) 155 target_under_test = analysistest.target_under_test(env) 156 asserts.equals(env, target_under_test.label.name, target_under_test[CcApiContributionInfo].name) 157 return analysistest.end(env) 158 159empty_library_name_gets_label_name_test = analysistest.make(_empty_library_name_gets_label_name_impl) 160 161def _empty_library_name_gets_label_name_test(): 162 test_name = "empty_library_name_gets_label_name" 163 subject_name = test_name + "_subject" 164 cc_api_contribution( 165 name = subject_name, 166 api = ":libfoo.map.txt", 167 tags = ["manual"], 168 ) 169 empty_library_name_gets_label_name_test( 170 name = test_name, 171 target_under_test = subject_name, 172 ) 173 return test_name 174 175def _nonempty_library_name_preferred_impl(ctx): 176 env = analysistest.begin(ctx) 177 target_under_test = analysistest.target_under_test(env) 178 asserts.equals(env, ctx.attr.expected_library_name, target_under_test[CcApiContributionInfo].name) 179 return analysistest.end(env) 180 181nonempty_library_name_preferred_test = analysistest.make( 182 impl = _nonempty_library_name_preferred_impl, 183 attrs = { 184 "expected_library_name": attr.string(), 185 }, 186) 187 188def _nonempty_library_name_preferred_test(): 189 test_name = "nonempty_library_name_preferred_test" 190 subject_name = test_name + "_subject" 191 library_name = "mylibrary" 192 cc_api_contribution( 193 name = subject_name, 194 library_name = library_name, 195 api = ":libfoo.map.txt", 196 tags = ["manual"], 197 ) 198 nonempty_library_name_preferred_test( 199 name = test_name, 200 target_under_test = subject_name, 201 expected_library_name = library_name, 202 ) 203 return test_name 204 205def _api_surfaces_attr_test_impl(ctx): 206 env = analysistest.begin(ctx) 207 target_under_test = analysistest.target_under_test(env) 208 asserts.equals(env, ctx.attr.expected_api_surfaces, target_under_test[CcApiContributionInfo].api_surfaces) 209 return analysistest.end(env) 210 211api_surfaces_attr_test = analysistest.make( 212 impl = _api_surfaces_attr_test_impl, 213 attrs = { 214 "expected_api_surfaces": attr.string_list(), 215 }, 216) 217 218def _api_surfaces_attr_test(): 219 test_name = "api_surfaces_attr_test" 220 subject_name = test_name + "_subject" 221 cc_api_contribution( 222 name = subject_name, 223 api = "libfoo.map.txt", 224 api_surfaces = ["publicapi", "module-libapi"], 225 tags = ["manual"], 226 ) 227 api_surfaces_attr_test( 228 name = test_name, 229 target_under_test = subject_name, 230 expected_api_surfaces = ["publicapi", "module-libapi"], 231 ) 232 return test_name 233 234def _api_headers_contribution_test_impl(ctx): 235 env = analysistest.begin(ctx) 236 target_under_test = analysistest.target_under_test(env) 237 asserts.equals(env, ctx.attr.expected_include_dirs, [hdr_info.root for hdr_info in target_under_test[CcApiContributionInfo].headers]) 238 return analysistest.end(env) 239 240api_headers_contribution_test = analysistest.make( 241 impl = _api_headers_contribution_test_impl, 242 attrs = { 243 "expected_include_dirs": attr.string_list(), 244 }, 245) 246 247def _api_headers_contribution_test(): 248 test_name = "api_headers_contribution_test" 249 subject_name = test_name + "_subject" 250 cc_api_contribution( 251 name = subject_name, 252 api = ":libfoo.map.txt", 253 hdrs = [ 254 subject_name + "_headers", 255 subject_name + "_library_headers", 256 ], 257 tags = ["manual"], 258 ) 259 cc_api_headers( 260 name = subject_name + "_headers", 261 hdrs = [], 262 include_dir = "dir1", 263 tags = ["manual"], 264 ) 265 cc_api_library_headers( 266 name = subject_name + "_library_headers", 267 export_includes = ["dir2", "dir3"], 268 tags = ["manual"], 269 ) 270 api_headers_contribution_test( 271 name = test_name, 272 target_under_test = subject_name, 273 expected_include_dirs = [ 274 "build/bazel/rules/apis/dir1", 275 "build/bazel/rules/apis/dir2", 276 "build/bazel/rules/apis/dir3", 277 ], 278 ) 279 return test_name 280 281def cc_api_test_suite(name): 282 native.test_suite( 283 name = name, 284 tests = [ 285 _empty_include_dir_test(), 286 _nonempty_include_dir_test(), 287 _api_library_headers_test(), 288 _api_path_is_relative_to_workspace_root_test(), 289 _empty_library_name_gets_label_name_test(), 290 _nonempty_library_name_preferred_test(), 291 _api_surfaces_attr_test(), 292 _api_headers_contribution_test(), 293 ], 294 ) 295