1# Copyright (C) 2017 The Dagger Authors. 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 15"""This file defines constants useful across the Dagger tests.""" 16 17load("@rules_java//java:defs.bzl", "java_library", "java_test") 18load("//:build_defs.bzl", "JAVA_RELEASE_MIN") 19load( 20 "@io_bazel_rules_kotlin//kotlin:kotlin.bzl", 21 "kt_jvm_library", 22 "kt_jvm_test", 23) 24 25# Defines a set of build variants and the list of extra javacopts to build with. 26# The key will be appended to the generated test names to ensure uniqueness. 27_NON_FUNCTIONAL_BUILD_VARIANTS = {None: []} 28_FUNCTIONAL_BUILD_VARIANTS = { 29 None: [], # The default build variant (no javacopts). 30 "ExtendsComponent": ["-Adagger.generatedClassExtendsComponent=enabled"], 31 "Shards": ["-Adagger.keysPerComponentShard=2"], 32 "FastInit": ["-Adagger.fastInit=enabled"], 33 "FastInit_Shards": ["-Adagger.fastInit=enabled", "-Adagger.keysPerComponentShard=2"], 34} 35 36def GenKtLibrary( 37 name, 38 srcs, 39 deps = None, 40 gen_library_deps = None, 41 plugins = None, 42 javacopts = None, 43 functional = True, 44 require_jdk7_syntax = True): 45 _GenTestsWithVariants( 46 library_rule_type = kt_jvm_library, 47 test_rule_type = None, 48 name = name, 49 srcs = srcs, 50 deps = deps, 51 gen_library_deps = gen_library_deps, 52 test_only_deps = None, 53 shard_count = None, 54 plugins = plugins, 55 javacopts = javacopts, 56 functional = functional, 57 require_jdk7_syntax = require_jdk7_syntax, 58 ) 59 60def GenKtTests( 61 name, 62 srcs, 63 deps = None, 64 gen_library_deps = None, 65 test_only_deps = None, 66 plugins = None, 67 javacopts = None, 68 shard_count = None, 69 functional = True, 70 require_jdk7_syntax = True): 71 _GenTestsWithVariants( 72 library_rule_type = kt_jvm_library, 73 test_rule_type = kt_jvm_test, 74 name = name, 75 srcs = srcs, 76 deps = deps, 77 gen_library_deps = gen_library_deps, 78 test_only_deps = test_only_deps, 79 plugins = plugins, 80 javacopts = javacopts, 81 shard_count = shard_count, 82 functional = functional, 83 require_jdk7_syntax = require_jdk7_syntax, 84 ) 85 86def GenJavaLibrary( 87 name, 88 srcs, 89 deps = None, 90 gen_library_deps = None, 91 plugins = None, 92 javacopts = None, 93 functional = True, 94 require_jdk7_syntax = True): 95 if any([src for src in srcs if src.endswith(".kt")]): 96 fail("GenJavaLibrary ':{0}' should not contain kotlin sources.".format(name)) 97 _GenTestsWithVariants( 98 library_rule_type = java_library, 99 test_rule_type = None, 100 name = name, 101 srcs = srcs, 102 deps = deps, 103 gen_library_deps = gen_library_deps, 104 test_only_deps = None, 105 plugins = plugins, 106 javacopts = javacopts, 107 shard_count = None, 108 functional = functional, 109 require_jdk7_syntax = require_jdk7_syntax, 110 ) 111 112def GenJavaTests( 113 name, 114 srcs, 115 deps = None, 116 gen_library_deps = None, 117 test_only_deps = None, 118 plugins = None, 119 javacopts = None, 120 shard_count = None, 121 functional = True, 122 require_jdk7_syntax = True): 123 if any([src for src in srcs if src.endswith(".kt")]): 124 fail("GenJavaTests ':{0}' should not contain kotlin sources.".format(name)) 125 _GenTestsWithVariants( 126 library_rule_type = java_library, 127 test_rule_type = java_test, 128 name = name, 129 srcs = srcs, 130 deps = deps, 131 gen_library_deps = gen_library_deps, 132 test_only_deps = test_only_deps, 133 plugins = plugins, 134 javacopts = javacopts, 135 shard_count = shard_count, 136 functional = functional, 137 require_jdk7_syntax = require_jdk7_syntax, 138 ) 139 140def GenRobolectricTests( 141 name, 142 srcs, 143 deps = None, 144 test_only_deps = None, 145 plugins = None, 146 javacopts = None, 147 shard_count = None, 148 functional = True, 149 require_jdk7_syntax = True, 150 manifest_values = None): 151 deps = (deps or []) + ["//:android_local_test_exports"] 152 _GenTestsWithVariants( 153 library_rule_type = native.android_library, 154 test_rule_type = native.android_local_test, 155 name = name, 156 srcs = srcs, 157 deps = deps, 158 gen_library_deps = None, 159 test_only_deps = test_only_deps, 160 plugins = plugins, 161 javacopts = javacopts, 162 shard_count = shard_count, 163 functional = functional, 164 require_jdk7_syntax = require_jdk7_syntax, 165 test_kwargs = {"manifest_values": manifest_values}, 166 ) 167 168def _GenTestsWithVariants( 169 library_rule_type, 170 test_rule_type, 171 name, 172 srcs, 173 deps, 174 gen_library_deps, 175 test_only_deps, 176 plugins, 177 javacopts, 178 shard_count, 179 functional, 180 require_jdk7_syntax, 181 test_kwargs = None): 182 test_files = [src for src in srcs if _is_test(src)] 183 supporting_files = [src for src in srcs if not _is_test(src)] 184 185 if test_rule_type and not test_files: 186 fail("':{0}' should contain at least 1 test source.".format(name)) 187 188 if not test_rule_type and test_files: 189 fail("':{0}' should not contain any test sources.".format(name)) 190 191 if test_kwargs == None: 192 test_kwargs = {} 193 194 if deps == None: 195 deps = [] 196 197 if gen_library_deps == None: 198 gen_library_deps = [] 199 200 if test_only_deps == None: 201 test_only_deps = [] 202 203 if plugins == None: 204 plugins = [] 205 206 if javacopts == None: 207 javacopts = [] 208 209 build_variants = _FUNCTIONAL_BUILD_VARIANTS if functional else _NON_FUNCTIONAL_BUILD_VARIANTS 210 for (variant_name, variant_javacopts) in build_variants.items(): 211 for is_ksp in (True, False): 212 if variant_name: 213 suffix = "_" + variant_name 214 tags = [variant_name] 215 216 # Add jvm_flags so that the mode can be accessed from within tests. 217 jvm_flags = ["-Ddagger.mode=" + variant_name] 218 else: 219 suffix = "" 220 tags = [] 221 jvm_flags = [] 222 223 if is_ksp: 224 continue # KSP not yet supported in Bazel 225 226 variant_deps = [canonical_dep_name(dep) + suffix for dep in gen_library_deps] 227 test_deps = deps + test_only_deps 228 if supporting_files: 229 supporting_files_name = name + suffix + ("_lib" if test_files else "") 230 _GenLibraryWithVariant( 231 library_rule_type = library_rule_type, 232 name = supporting_files_name, 233 srcs = supporting_files, 234 tags = tags, 235 deps = deps + variant_deps, 236 plugins = plugins, 237 javacopts = javacopts + variant_javacopts, 238 functional = functional, 239 require_jdk7_syntax = require_jdk7_syntax, 240 ) 241 test_deps.append(supporting_files_name) 242 243 for test_file in test_files: 244 test_name = test_file.rsplit(".", 1)[0] 245 _GenTestWithVariant( 246 library_rule_type = library_rule_type, 247 test_rule_type = test_rule_type, 248 name = test_name + suffix, 249 srcs = [test_file], 250 tags = tags, 251 deps = test_deps + variant_deps, 252 plugins = plugins, 253 javacopts = javacopts + variant_javacopts, 254 shard_count = shard_count, 255 jvm_flags = jvm_flags, 256 functional = functional, 257 test_kwargs = test_kwargs, 258 ) 259 260def _GenLibraryWithVariant( 261 library_rule_type, 262 name, 263 srcs, 264 tags, 265 deps, 266 plugins, 267 javacopts, 268 functional, 269 require_jdk7_syntax): 270 if functional and require_jdk7_syntax: 271 # TODO(b/261894425): Decide if we still want to apply JAVA_RELEASE_MIN by default. 272 # Note: Technically, we should also apply JAVA_RELEASE_MIN to tests too, since we have 273 # Dagger code in there as well, but we keep it only on libraries for legacy reasons, and 274 # fixing tests to be jdk7 compatible would require a bit of work. We should decide on 275 # b/261894425 before committing to that work. 276 library_javacopts_kwargs = {"javacopts": javacopts + JAVA_RELEASE_MIN} 277 else: 278 library_javacopts_kwargs = {"javacopts": javacopts} 279 280 # TODO(bcorso): Add javacopts explicitly once kt_jvm_test supports them. 281 if library_rule_type in [kt_jvm_library]: 282 library_javacopts_kwargs = {} 283 library_rule_type( 284 name = name, 285 testonly = 1, 286 srcs = srcs, 287 plugins = plugins, 288 tags = tags, 289 deps = deps, 290 **library_javacopts_kwargs 291 ) 292 if functional and _is_hjar_test_supported(library_rule_type): 293 _hjar_test(name, tags) 294 295def _GenTestWithVariant( 296 library_rule_type, 297 test_rule_type, 298 name, 299 srcs, 300 tags, 301 deps, 302 plugins, 303 javacopts, 304 shard_count, 305 jvm_flags, 306 functional, 307 test_kwargs): 308 test_files = [src for src in srcs if _is_test(src)] 309 if len(test_files) != 1: 310 fail("Expected 1 test source but found multiples: {0}".format(test_files)) 311 312 should_add_goldens = not functional and (test_rule_type == java_test) 313 test_name = test_files[0].rsplit(".", 1)[0] 314 prefix_path = "src/test/java/" 315 package_name = native.package_name() 316 if package_name.find("javatests/") != -1: 317 prefix_path = "javatests/" 318 if should_add_goldens: 319 test_kwargs["resources"] = native.glob(["goldens/%s_*" % test_name]) 320 test_class = (package_name + "/" + test_name).rpartition(prefix_path)[2].replace("/", ".") 321 test_kwargs_with_javacopts = {"javacopts": javacopts} 322 323 # TODO(bcorso): Add javacopts explicitly once kt_jvm_test supports them. 324 if test_rule_type == kt_jvm_test: 325 test_kwargs_with_javacopts = {} 326 test_kwargs_with_javacopts.update(test_kwargs) 327 test_rule_type( 328 name = name, 329 srcs = srcs, 330 jvm_flags = jvm_flags, 331 plugins = plugins, 332 tags = tags, 333 shard_count = shard_count, 334 test_class = test_class, 335 deps = deps, 336 **test_kwargs_with_javacopts 337 ) 338 339def _is_hjar_test_supported(bazel_rule): 340 return bazel_rule not in ( 341 kt_jvm_library, 342 kt_jvm_test, 343 native.android_library, 344 native.android_local_test, 345 ) 346 347def _hjar_test(name, tags): 348 pass 349 350def _is_test(src): 351 return src.endswith("Test.java") or src.endswith("Test.kt") 352 353def canonical_dep_name(dep): 354 if dep.startswith(":"): 355 dep = "//" + native.package_name() + dep 356 dep_label = Label(dep) 357 return "//" + dep_label.package + ":" + dep_label.name 358