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