• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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