• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2022 The Android Open Source Project
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"""cc_test macro for building native tests with Bazel."""
16
17load("//build/bazel/rules/cc:cc_library_common.bzl", "CcAndroidMkInfo")
18load("//build/bazel/rules/cc:stripped_cc_common.bzl", "CcUnstrippedInfo", "StrippedCcBinaryInfo")
19load("//build/bazel/rules/tradefed:tradefed.bzl", "tradefed_host_driven_test")
20load(":cc_binary.bzl", "cc_binary")
21
22# TODO(b/244559183): Keep this in sync with cc/test.go#linkerFlags
23_gtest_copts = select({
24    "//build/bazel/platforms/os:linux_glibc": ["-DGTEST_OS_LINUX"],
25    "//build/bazel/platforms/os:darwin": ["-DGTEST_OS_MAC"],
26    "//build/bazel/platforms/os:windows": ["-DGTEST_OS_WINDOWS"],
27    "//conditions:default": ["-DGTEST_OS_LINUX_ANDROID"],
28}) + select({
29    "//build/bazel/platforms/os:android": [],
30    "//conditions:default": ["-O0", "-g"],  # here, default == host platform
31}) + [
32    "-DGTEST_HAS_STD_STRING",
33    "-Wno-unused-result",  # TODO(b/244433518): Figure out why this is necessary in the bazel compile action.
34]
35
36_gtest_deps = [
37    "//external/googletest/googletest:libgtest_main",
38    "//external/googletest/googletest:libgtest",
39]
40
41_pass_through_providers = [
42    CcInfo,
43    InstrumentedFilesInfo,
44    DebugPackageInfo,
45    OutputGroupInfo,
46    StrippedCcBinaryInfo,
47    CcUnstrippedInfo,
48    CcAndroidMkInfo,
49]
50
51def cc_test(
52        name,
53        copts = [],
54        deps = [],
55        dynamic_deps = [],
56        gtest = True,
57        isolated = True,  # TODO(b/244432609): currently no-op. @unused
58        tags = [],
59        tidy = None,
60        tidy_checks = None,
61        tidy_checks_as_errors = None,
62        tidy_flags = None,
63        tidy_disabled_srcs = None,
64        tidy_timeout_srcs = None,
65        test_config = None,
66        template_test_config = None,
67        template_configs = [],
68        template_install_base = None,
69        **kwargs):
70    # NOTE: Keep this in sync with cc/test.go#linkerDeps
71    if gtest:
72        # TODO(b/244433197): handle ctx.useSdk() && ctx.Device() case to link against the ndk variants of the gtest libs.
73        # TODO(b/244432609): handle isolated = True to link against libgtest_isolated_main and liblog (dynamically)
74        deps = deps + _gtest_deps
75        copts = copts + _gtest_copts
76
77    # A cc_test is essentially the same as a cc_binary. Let's reuse the
78    # implementation for now and factor the common bits out as necessary.
79    test_binary_name = name + "__test_binary"
80    cc_binary(
81        name = test_binary_name,
82        copts = copts,
83        deps = deps,
84        dynamic_deps = dynamic_deps,
85        generate_cc_test = True,
86        tidy = tidy,
87        tidy_checks = tidy_checks,
88        tidy_checks_as_errors = tidy_checks_as_errors,
89        tidy_flags = tidy_flags,
90        tidy_disabled_srcs = tidy_disabled_srcs,
91        tidy_timeout_srcs = tidy_timeout_srcs,
92        tags = tags + ["manual"],
93        **kwargs
94    )
95
96    # Host only test with no tradefed.
97    # Compatability is left out for now so as not to break mix build.
98    # which breaks when modules are skipped with --config=android
99    without_tradefed_test_name = name + "__without_tradefed_test"
100    cc_runner_test(
101        name = without_tradefed_test_name,
102        binary = test_binary_name,
103        test = test_binary_name,
104        tags = ["manual"],
105    )
106
107    # Tradefed host driven test
108    tradefed_host_driven_test_name = name + "__tradefed_host_driven_test"
109    if not test_config and not template_test_config:
110        template_test_config = select({
111            "//build/bazel/rules/tradefed:android_host_driven_tradefed_test": "//build/make/core:native_test_config_template.xml",
112            "//build/bazel/rules/tradefed:linux_host_driven_tradefed_test": "//build/make/core:native_host_test_config_template.xml",
113            "//conditions:default": "//build/make/core:native_test_config_template.xml",
114        })
115    tradefed_host_driven_test(
116        name = tradefed_host_driven_test_name,
117        test_identifier = name,
118        test = test_binary_name,
119        test_config = test_config,
120        template_test_config = template_test_config,
121        template_configs = template_configs,
122        template_install_base = template_install_base,
123        tags = ["manual"],
124    )
125
126    # TODO(b/264792912) update to use proper config/tags to determine which test to run.
127    cc_runner_test(
128        name = name,
129        binary = test_binary_name,
130        test = select({
131            "//build/bazel/rules/tradefed:android_host_driven_tradefed_test": tradefed_host_driven_test_name,
132            "//build/bazel/rules/tradefed:linux_host_driven_tradefed_test": tradefed_host_driven_test_name,
133            "//conditions:default": without_tradefed_test_name,
134        }),
135    )
136
137def _cc_runner_test_impl(ctx):
138    executable = ctx.actions.declare_file(ctx.attr.name + "__cc_runner_test")
139    ctx.actions.symlink(
140        output = executable,
141        target_file = ctx.attr.test.files_to_run.executable,
142    )
143
144    # Gather runfiles.
145    runfiles = ctx.runfiles()
146    runfiles = runfiles.merge_all([
147        ctx.attr.binary.default_runfiles,
148        ctx.attr.test.default_runfiles,
149    ])
150
151    # Propagate providers of the included binary
152    # Those providers are used to populate attributes of the mixed build.
153    providers = collect_providers(ctx.attr.binary, _pass_through_providers)
154    return [DefaultInfo(
155        executable = executable,
156        runfiles = runfiles,
157    )] + providers
158
159cc_runner_test = rule(
160    doc = "A wrapper rule used to run a test and also propagates providers",
161    attrs = {
162        "binary": attr.label(
163            doc = "Binary that providers should be propagated to next rule // mix build.",
164        ),
165        "test": attr.label(
166            doc = "Test to run.",
167        ),
168    },
169    test = True,
170    implementation = _cc_runner_test_impl,
171    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
172)
173
174def collect_providers(dep, provider_types):
175    """Returns list of providers from dependency that match the provider types"""
176    providers = []
177    for provider in provider_types:
178        if provider in dep:
179            providers.append(dep[provider])
180    return providers
181