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