xref: /aosp_15_r20/build/bazel/rules/cc/clang_tidy_test.bzl (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project
2*7594170eSAndroid Build Coastguard Worker#
3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*7594170eSAndroid Build Coastguard Worker#
7*7594170eSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
8*7594170eSAndroid Build Coastguard Worker#
9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*7594170eSAndroid Build Coastguard Worker# limitations under the License.
14*7594170eSAndroid Build Coastguard Worker
15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:new_sets.bzl", "sets")
16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
17*7594170eSAndroid Build Coastguard Workerload(
18*7594170eSAndroid Build Coastguard Worker    "//build/bazel/rules/test_common:args.bzl",
19*7594170eSAndroid Build Coastguard Worker    "get_all_args_with_prefix",
20*7594170eSAndroid Build Coastguard Worker    "get_single_arg_with_prefix",
21*7594170eSAndroid Build Coastguard Worker)
22*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules/test_common:rules.bzl", "expect_failure_test")
23*7594170eSAndroid Build Coastguard Workerload(":cc_library_static.bzl", "cc_library_static")
24*7594170eSAndroid Build Coastguard Workerload(":clang_tidy.bzl", "generate_clang_tidy_actions")
25*7594170eSAndroid Build Coastguard Worker
26*7594170eSAndroid Build Coastguard Worker_PACKAGE_HEADER_FILTER = "^build/bazel/rules/cc/"
27*7594170eSAndroid Build Coastguard Worker_DEFAULT_GLOBAL_CHECKS = [
28*7594170eSAndroid Build Coastguard Worker    "android-*",
29*7594170eSAndroid Build Coastguard Worker    "bugprone-*",
30*7594170eSAndroid Build Coastguard Worker    "cert-*",
31*7594170eSAndroid Build Coastguard Worker    "clang-diagnostic-unused-command-line-argument",
32*7594170eSAndroid Build Coastguard Worker    "google-build-explicit-make-pair",
33*7594170eSAndroid Build Coastguard Worker    "google-build-namespaces",
34*7594170eSAndroid Build Coastguard Worker    "google-runtime-operator",
35*7594170eSAndroid Build Coastguard Worker    "google-upgrade-*",
36*7594170eSAndroid Build Coastguard Worker    "misc-*",
37*7594170eSAndroid Build Coastguard Worker    "performance-*",
38*7594170eSAndroid Build Coastguard Worker    "portability-*",
39*7594170eSAndroid Build Coastguard Worker    "-bugprone-assignment-in-if-condition",
40*7594170eSAndroid Build Coastguard Worker    "-bugprone-easily-swappable-parameters",
41*7594170eSAndroid Build Coastguard Worker    "-bugprone-narrowing-conversions",
42*7594170eSAndroid Build Coastguard Worker    "-misc-const-correctness",
43*7594170eSAndroid Build Coastguard Worker    "-misc-no-recursion",
44*7594170eSAndroid Build Coastguard Worker    "-misc-non-private-member-variables-in-classes",
45*7594170eSAndroid Build Coastguard Worker    "-misc-unused-parameters",
46*7594170eSAndroid Build Coastguard Worker    "-performance-no-int-to-ptr",
47*7594170eSAndroid Build Coastguard Worker    "-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling",
48*7594170eSAndroid Build Coastguard Worker]
49*7594170eSAndroid Build Coastguard Worker_DEFAULT_CHECKS = [
50*7594170eSAndroid Build Coastguard Worker    "-misc-no-recursion",
51*7594170eSAndroid Build Coastguard Worker    "-readability-function-cognitive-complexity",
52*7594170eSAndroid Build Coastguard Worker    "-bugprone-unchecked-optional-access",
53*7594170eSAndroid Build Coastguard Worker    "-bugprone-reserved-identifier*",
54*7594170eSAndroid Build Coastguard Worker    "-cert-dcl51-cpp",
55*7594170eSAndroid Build Coastguard Worker    "-cert-dcl37-c",
56*7594170eSAndroid Build Coastguard Worker    "-readability-qualified-auto",
57*7594170eSAndroid Build Coastguard Worker    "-bugprone-implicit-widening-of-multiplication-result",
58*7594170eSAndroid Build Coastguard Worker    "-bugprone-easily-swappable-parameters",
59*7594170eSAndroid Build Coastguard Worker    "-cert-err33-c",
60*7594170eSAndroid Build Coastguard Worker    "-bugprone-unchecked-optional-access",
61*7594170eSAndroid Build Coastguard Worker    "-misc-use-anonymous-namespace",
62*7594170eSAndroid Build Coastguard Worker    "-performance-avoid-endl",
63*7594170eSAndroid Build Coastguard Worker]
64*7594170eSAndroid Build Coastguard Worker_DEFAULT_CHECKS_AS_ERRORS = [
65*7594170eSAndroid Build Coastguard Worker    "-bugprone-assignment-in-if-condition",
66*7594170eSAndroid Build Coastguard Worker    "-bugprone-branch-clone",
67*7594170eSAndroid Build Coastguard Worker    "-bugprone-signed-char-misuse",
68*7594170eSAndroid Build Coastguard Worker    "-misc-const-correctness",
69*7594170eSAndroid Build Coastguard Worker    "-bugprone-unsafe-functions",
70*7594170eSAndroid Build Coastguard Worker    "-cert-msc24-c",
71*7594170eSAndroid Build Coastguard Worker    "-cert-msc33-c",
72*7594170eSAndroid Build Coastguard Worker    "-modernize-type-traits",
73*7594170eSAndroid Build Coastguard Worker    "-readability-avoid-unconditional-preprocessor-if",
74*7594170eSAndroid Build Coastguard Worker]
75*7594170eSAndroid Build Coastguard Worker_EXTRA_ARGS_BEFORE = [
76*7594170eSAndroid Build Coastguard Worker    "-D__clang_analyzer__",
77*7594170eSAndroid Build Coastguard Worker    "-Xclang",
78*7594170eSAndroid Build Coastguard Worker    "-analyzer-config",
79*7594170eSAndroid Build Coastguard Worker    "-Xclang",
80*7594170eSAndroid Build Coastguard Worker    "c++-temp-dtor-inlining=false",
81*7594170eSAndroid Build Coastguard Worker]
82*7594170eSAndroid Build Coastguard Worker
83*7594170eSAndroid Build Coastguard Workerdef _clang_tidy_impl(ctx):
84*7594170eSAndroid Build Coastguard Worker    tidy_outs = generate_clang_tidy_actions(
85*7594170eSAndroid Build Coastguard Worker        ctx,
86*7594170eSAndroid Build Coastguard Worker        ctx.attr.copts,
87*7594170eSAndroid Build Coastguard Worker        ctx.attr.deps,
88*7594170eSAndroid Build Coastguard Worker        ctx.files.srcs,
89*7594170eSAndroid Build Coastguard Worker        ctx.files.hdrs,
90*7594170eSAndroid Build Coastguard Worker        ctx.attr.language,
91*7594170eSAndroid Build Coastguard Worker        ctx.attr.tidy_flags,
92*7594170eSAndroid Build Coastguard Worker        ctx.attr.tidy_checks,
93*7594170eSAndroid Build Coastguard Worker        ctx.attr.tidy_checks_as_errors,
94*7594170eSAndroid Build Coastguard Worker        ctx.attr.tidy_timeout_srcs,
95*7594170eSAndroid Build Coastguard Worker    )
96*7594170eSAndroid Build Coastguard Worker    return [
97*7594170eSAndroid Build Coastguard Worker        DefaultInfo(files = depset(tidy_outs)),
98*7594170eSAndroid Build Coastguard Worker    ]
99*7594170eSAndroid Build Coastguard Worker
100*7594170eSAndroid Build Coastguard Worker_clang_tidy = rule(
101*7594170eSAndroid Build Coastguard Worker    implementation = _clang_tidy_impl,
102*7594170eSAndroid Build Coastguard Worker    attrs = {
103*7594170eSAndroid Build Coastguard Worker        "srcs": attr.label_list(allow_files = True),
104*7594170eSAndroid Build Coastguard Worker        "deps": attr.label_list(),
105*7594170eSAndroid Build Coastguard Worker        "copts": attr.string_list(),
106*7594170eSAndroid Build Coastguard Worker        "hdrs": attr.label_list(allow_files = True),
107*7594170eSAndroid Build Coastguard Worker        "language": attr.string(values = ["c++", "c"], default = "c++"),
108*7594170eSAndroid Build Coastguard Worker        "tidy_checks": attr.string_list(),
109*7594170eSAndroid Build Coastguard Worker        "tidy_checks_as_errors": attr.string_list(),
110*7594170eSAndroid Build Coastguard Worker        "tidy_flags": attr.string_list(),
111*7594170eSAndroid Build Coastguard Worker        "tidy_timeout_srcs": attr.label_list(allow_files = True),
112*7594170eSAndroid Build Coastguard Worker        "_clang_tidy_sh": attr.label(
113*7594170eSAndroid Build Coastguard Worker            default = Label("@//prebuilts/clang/host/linux-x86:clang-tidy.sh"),
114*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
115*7594170eSAndroid Build Coastguard Worker            executable = True,
116*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
117*7594170eSAndroid Build Coastguard Worker            doc = "The clang tidy shell wrapper",
118*7594170eSAndroid Build Coastguard Worker        ),
119*7594170eSAndroid Build Coastguard Worker        "_clang_tidy": attr.label(
120*7594170eSAndroid Build Coastguard Worker            default = Label("@//prebuilts/clang/host/linux-x86:clang-tidy"),
121*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
122*7594170eSAndroid Build Coastguard Worker            executable = True,
123*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
124*7594170eSAndroid Build Coastguard Worker            doc = "The clang tidy executable",
125*7594170eSAndroid Build Coastguard Worker        ),
126*7594170eSAndroid Build Coastguard Worker        "_clang_tidy_real": attr.label(
127*7594170eSAndroid Build Coastguard Worker            default = Label("@//prebuilts/clang/host/linux-x86:clang-tidy.real"),
128*7594170eSAndroid Build Coastguard Worker            allow_single_file = True,
129*7594170eSAndroid Build Coastguard Worker            executable = True,
130*7594170eSAndroid Build Coastguard Worker            cfg = "exec",
131*7594170eSAndroid Build Coastguard Worker        ),
132*7594170eSAndroid Build Coastguard Worker        "_with_tidy": attr.label(
133*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/flags/cc/tidy:with_tidy",
134*7594170eSAndroid Build Coastguard Worker        ),
135*7594170eSAndroid Build Coastguard Worker        "_allow_local_tidy_true": attr.label(
136*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/flags/cc/tidy:allow_local_tidy_true",
137*7594170eSAndroid Build Coastguard Worker        ),
138*7594170eSAndroid Build Coastguard Worker        "_with_tidy_flags": attr.label(
139*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/flags/cc/tidy:with_tidy_flags",
140*7594170eSAndroid Build Coastguard Worker        ),
141*7594170eSAndroid Build Coastguard Worker        "_default_tidy_header_dirs": attr.label(
142*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/flags/cc/tidy:default_tidy_header_dirs",
143*7594170eSAndroid Build Coastguard Worker        ),
144*7594170eSAndroid Build Coastguard Worker        "_tidy_timeout": attr.label(
145*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/flags/cc/tidy:tidy_timeout",
146*7594170eSAndroid Build Coastguard Worker        ),
147*7594170eSAndroid Build Coastguard Worker        "_tidy_checks": attr.label(
148*7594170eSAndroid Build Coastguard Worker            default = "//build/bazel/product_config:tidy_checks",
149*7594170eSAndroid Build Coastguard Worker        ),
150*7594170eSAndroid Build Coastguard Worker    },
151*7594170eSAndroid Build Coastguard Worker    toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
152*7594170eSAndroid Build Coastguard Worker    fragments = ["cpp"],
153*7594170eSAndroid Build Coastguard Worker)
154*7594170eSAndroid Build Coastguard Worker
155*7594170eSAndroid Build Coastguard Workerdef _get_all_arg(env, actions, argname):
156*7594170eSAndroid Build Coastguard Worker    args = get_all_args_with_prefix(actions[0].argv, argname)
157*7594170eSAndroid Build Coastguard Worker    asserts.false(env, args == [], "could not arguments that start with `{}`".format(argname))
158*7594170eSAndroid Build Coastguard Worker    return args
159*7594170eSAndroid Build Coastguard Worker
160*7594170eSAndroid Build Coastguard Workerdef _get_single_arg(actions, argname):
161*7594170eSAndroid Build Coastguard Worker    return get_single_arg_with_prefix(actions[0].argv, argname)
162*7594170eSAndroid Build Coastguard Worker
163*7594170eSAndroid Build Coastguard Workerdef _checks_test_impl(ctx):
164*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
165*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
166*7594170eSAndroid Build Coastguard Worker
167*7594170eSAndroid Build Coastguard Worker    checks = _get_single_arg(actions, "-checks=").split(",")
168*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(env, sets.make(ctx.attr.expected_checks), sets.make(checks))
169*7594170eSAndroid Build Coastguard Worker    if len(ctx.attr.unexpected_checks) > 0:
170*7594170eSAndroid Build Coastguard Worker        for c in ctx.attr.unexpected_checks:
171*7594170eSAndroid Build Coastguard Worker            asserts.false(env, c in checks, "found unexpected check in -checks flag: %s" % c)
172*7594170eSAndroid Build Coastguard Worker
173*7594170eSAndroid Build Coastguard Worker    checks_as_errors = _get_single_arg(actions, "-warnings-as-errors=").split(",")
174*7594170eSAndroid Build Coastguard Worker    asserts.set_equals(env, sets.make(ctx.attr.expected_checks_as_errors), sets.make(checks_as_errors))
175*7594170eSAndroid Build Coastguard Worker
176*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
177*7594170eSAndroid Build Coastguard Worker
178*7594170eSAndroid Build Coastguard Worker_checks_test = analysistest.make(
179*7594170eSAndroid Build Coastguard Worker    _checks_test_impl,
180*7594170eSAndroid Build Coastguard Worker    attrs = {
181*7594170eSAndroid Build Coastguard Worker        "expected_checks": attr.string_list(mandatory = True),
182*7594170eSAndroid Build Coastguard Worker        "expected_checks_as_errors": attr.string_list(mandatory = True),
183*7594170eSAndroid Build Coastguard Worker        "unexpected_checks": attr.string_list(),
184*7594170eSAndroid Build Coastguard Worker    },
185*7594170eSAndroid Build Coastguard Worker)
186*7594170eSAndroid Build Coastguard Worker
187*7594170eSAndroid Build Coastguard Workerdef _copts_test_impl(ctx):
188*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
189*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
190*7594170eSAndroid Build Coastguard Worker
191*7594170eSAndroid Build Coastguard Worker    args = actions[0].argv
192*7594170eSAndroid Build Coastguard Worker    clang_flags = []
193*7594170eSAndroid Build Coastguard Worker    for i, a in enumerate(args):
194*7594170eSAndroid Build Coastguard Worker        if a == "--" and len(args) > i + 1:
195*7594170eSAndroid Build Coastguard Worker            clang_flags = args[i + 1:]
196*7594170eSAndroid Build Coastguard Worker            break
197*7594170eSAndroid Build Coastguard Worker    asserts.true(
198*7594170eSAndroid Build Coastguard Worker        env,
199*7594170eSAndroid Build Coastguard Worker        len(clang_flags) > 0,
200*7594170eSAndroid Build Coastguard Worker        "no flags passed to clang; all arguments: %s" % args,
201*7594170eSAndroid Build Coastguard Worker    )
202*7594170eSAndroid Build Coastguard Worker
203*7594170eSAndroid Build Coastguard Worker    for expected_arg in ctx.attr.expected_copts:
204*7594170eSAndroid Build Coastguard Worker        asserts.true(
205*7594170eSAndroid Build Coastguard Worker            env,
206*7594170eSAndroid Build Coastguard Worker            expected_arg in clang_flags,
207*7594170eSAndroid Build Coastguard Worker            "expected `%s` not present in clang flags" % expected_arg,
208*7594170eSAndroid Build Coastguard Worker        )
209*7594170eSAndroid Build Coastguard Worker
210*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
211*7594170eSAndroid Build Coastguard Worker
212*7594170eSAndroid Build Coastguard Worker_copts_test = analysistest.make(
213*7594170eSAndroid Build Coastguard Worker    _copts_test_impl,
214*7594170eSAndroid Build Coastguard Worker    attrs = {
215*7594170eSAndroid Build Coastguard Worker        "expected_copts": attr.string_list(mandatory = True),
216*7594170eSAndroid Build Coastguard Worker    },
217*7594170eSAndroid Build Coastguard Worker)
218*7594170eSAndroid Build Coastguard Worker
219*7594170eSAndroid Build Coastguard Workerdef _tidy_flags_test_impl(ctx):
220*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
221*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
222*7594170eSAndroid Build Coastguard Worker
223*7594170eSAndroid Build Coastguard Worker    args = actions[0].argv
224*7594170eSAndroid Build Coastguard Worker    tidy_flags = []
225*7594170eSAndroid Build Coastguard Worker    for i, a in enumerate(args):
226*7594170eSAndroid Build Coastguard Worker        if a == "--" and len(args) > i + 1:
227*7594170eSAndroid Build Coastguard Worker            tidy_flags = args[:i]
228*7594170eSAndroid Build Coastguard Worker    asserts.true(
229*7594170eSAndroid Build Coastguard Worker        env,
230*7594170eSAndroid Build Coastguard Worker        len(tidy_flags) > 0,
231*7594170eSAndroid Build Coastguard Worker        "no tidy flags passed to clang-tidy; all arguments: %s" % args,
232*7594170eSAndroid Build Coastguard Worker    )
233*7594170eSAndroid Build Coastguard Worker
234*7594170eSAndroid Build Coastguard Worker    for expected_arg in ctx.attr.expected_tidy_flags:
235*7594170eSAndroid Build Coastguard Worker        asserts.true(
236*7594170eSAndroid Build Coastguard Worker            env,
237*7594170eSAndroid Build Coastguard Worker            expected_arg in tidy_flags,
238*7594170eSAndroid Build Coastguard Worker            "expected `%s` not present in flags to clang-tidy" % expected_arg,
239*7594170eSAndroid Build Coastguard Worker        )
240*7594170eSAndroid Build Coastguard Worker
241*7594170eSAndroid Build Coastguard Worker    header_filter = _get_single_arg(actions, "-header-filter=")
242*7594170eSAndroid Build Coastguard Worker    asserts.true(
243*7594170eSAndroid Build Coastguard Worker        env,
244*7594170eSAndroid Build Coastguard Worker        header_filter == ctx.attr.expected_header_filter,
245*7594170eSAndroid Build Coastguard Worker        (
246*7594170eSAndroid Build Coastguard Worker            "expected header-filter to have value `%s`; got `%s`" %
247*7594170eSAndroid Build Coastguard Worker            (ctx.attr.expected_header_filter, header_filter)
248*7594170eSAndroid Build Coastguard Worker        ),
249*7594170eSAndroid Build Coastguard Worker    )
250*7594170eSAndroid Build Coastguard Worker
251*7594170eSAndroid Build Coastguard Worker    extra_arg_before = _get_all_arg(env, actions, "-extra-arg-before=")
252*7594170eSAndroid Build Coastguard Worker    for expected_arg in ctx.attr.expected_extra_arg_before:
253*7594170eSAndroid Build Coastguard Worker        asserts.true(
254*7594170eSAndroid Build Coastguard Worker            env,
255*7594170eSAndroid Build Coastguard Worker            expected_arg in extra_arg_before,
256*7594170eSAndroid Build Coastguard Worker            "did not find expected flag `%s` in args to clang-tidy" % expected_arg,
257*7594170eSAndroid Build Coastguard Worker        )
258*7594170eSAndroid Build Coastguard Worker
259*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
260*7594170eSAndroid Build Coastguard Worker
261*7594170eSAndroid Build Coastguard Worker_tidy_flags_test = analysistest.make(
262*7594170eSAndroid Build Coastguard Worker    _tidy_flags_test_impl,
263*7594170eSAndroid Build Coastguard Worker    attrs = {
264*7594170eSAndroid Build Coastguard Worker        "expected_tidy_flags": attr.string_list(),
265*7594170eSAndroid Build Coastguard Worker        "expected_header_filter": attr.string(mandatory = True),
266*7594170eSAndroid Build Coastguard Worker        "expected_extra_arg_before": attr.string_list(),
267*7594170eSAndroid Build Coastguard Worker    },
268*7594170eSAndroid Build Coastguard Worker)
269*7594170eSAndroid Build Coastguard Worker
270*7594170eSAndroid Build Coastguard Workerdef _test_clang_tidy():
271*7594170eSAndroid Build Coastguard Worker    name = "checks"
272*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
273*7594170eSAndroid Build Coastguard Worker    checks_test_name = test_name + "_checks"
274*7594170eSAndroid Build Coastguard Worker    copts_test_name = test_name + "_copts"
275*7594170eSAndroid Build Coastguard Worker    tidy_flags_test_name = test_name + "_tidy_flags"
276*7594170eSAndroid Build Coastguard Worker
277*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
278*7594170eSAndroid Build Coastguard Worker        name = name,
279*7594170eSAndroid Build Coastguard Worker        # clang-tidy operates differently on generated and non-generated files
280*7594170eSAndroid Build Coastguard Worker        # use test_srcs so that the tidy rule doesn't think these are genearted
281*7594170eSAndroid Build Coastguard Worker        # files
282*7594170eSAndroid Build Coastguard Worker        srcs = ["//build/bazel/rules/cc/testing:test_srcs"],
283*7594170eSAndroid Build Coastguard Worker        copts = ["-asdf1", "-asdf2"],
284*7594170eSAndroid Build Coastguard Worker        tidy_flags = ["-tidy-flag1", "-tidy-flag2"],
285*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
286*7594170eSAndroid Build Coastguard Worker    )
287*7594170eSAndroid Build Coastguard Worker
288*7594170eSAndroid Build Coastguard Worker    _checks_test(
289*7594170eSAndroid Build Coastguard Worker        name = checks_test_name,
290*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
291*7594170eSAndroid Build Coastguard Worker        expected_checks = _DEFAULT_CHECKS + _DEFAULT_GLOBAL_CHECKS,
292*7594170eSAndroid Build Coastguard Worker        expected_checks_as_errors = _DEFAULT_CHECKS_AS_ERRORS,
293*7594170eSAndroid Build Coastguard Worker    )
294*7594170eSAndroid Build Coastguard Worker
295*7594170eSAndroid Build Coastguard Worker    _copts_test(
296*7594170eSAndroid Build Coastguard Worker        name = copts_test_name,
297*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
298*7594170eSAndroid Build Coastguard Worker        expected_copts = ["-asdf1", "-asdf2"],
299*7594170eSAndroid Build Coastguard Worker    )
300*7594170eSAndroid Build Coastguard Worker
301*7594170eSAndroid Build Coastguard Worker    _tidy_flags_test(
302*7594170eSAndroid Build Coastguard Worker        name = tidy_flags_test_name,
303*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
304*7594170eSAndroid Build Coastguard Worker        expected_tidy_flags = ["-tidy-flag1", "-tidy-flag2"],
305*7594170eSAndroid Build Coastguard Worker        expected_header_filter = _PACKAGE_HEADER_FILTER,
306*7594170eSAndroid Build Coastguard Worker        expected_extra_arg_before = _EXTRA_ARGS_BEFORE,
307*7594170eSAndroid Build Coastguard Worker    )
308*7594170eSAndroid Build Coastguard Worker
309*7594170eSAndroid Build Coastguard Worker    return [
310*7594170eSAndroid Build Coastguard Worker        checks_test_name,
311*7594170eSAndroid Build Coastguard Worker        copts_test_name,
312*7594170eSAndroid Build Coastguard Worker        tidy_flags_test_name,
313*7594170eSAndroid Build Coastguard Worker    ]
314*7594170eSAndroid Build Coastguard Worker
315*7594170eSAndroid Build Coastguard Workerdef _test_custom_header_dir():
316*7594170eSAndroid Build Coastguard Worker    name = "custom_header_dir"
317*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
318*7594170eSAndroid Build Coastguard Worker
319*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
320*7594170eSAndroid Build Coastguard Worker        name = name,
321*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
322*7594170eSAndroid Build Coastguard Worker        tidy_flags = ["-header-filter=dir1/"],
323*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
324*7594170eSAndroid Build Coastguard Worker    )
325*7594170eSAndroid Build Coastguard Worker
326*7594170eSAndroid Build Coastguard Worker    _tidy_flags_test(
327*7594170eSAndroid Build Coastguard Worker        name = test_name,
328*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
329*7594170eSAndroid Build Coastguard Worker        expected_header_filter = "dir1/",
330*7594170eSAndroid Build Coastguard Worker    )
331*7594170eSAndroid Build Coastguard Worker
332*7594170eSAndroid Build Coastguard Worker    return [
333*7594170eSAndroid Build Coastguard Worker        test_name,
334*7594170eSAndroid Build Coastguard Worker    ]
335*7594170eSAndroid Build Coastguard Worker
336*7594170eSAndroid Build Coastguard Workerdef _test_disabled_checks_are_removed():
337*7594170eSAndroid Build Coastguard Worker    name = "disabled_checks_are_removed"
338*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
339*7594170eSAndroid Build Coastguard Worker
340*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
341*7594170eSAndroid Build Coastguard Worker        name = name,
342*7594170eSAndroid Build Coastguard Worker        # clang-tidy operates differently on generated and non-generated files.
343*7594170eSAndroid Build Coastguard Worker        # use test_srcs so that the tidy rule doesn't think these are genearted
344*7594170eSAndroid Build Coastguard Worker        # files
345*7594170eSAndroid Build Coastguard Worker        srcs = ["//build/bazel/rules/cc/testing:test_srcs"],
346*7594170eSAndroid Build Coastguard Worker        tidy_checks = ["misc-no-recursion", "readability-function-cognitive-complexity"],
347*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
348*7594170eSAndroid Build Coastguard Worker    )
349*7594170eSAndroid Build Coastguard Worker
350*7594170eSAndroid Build Coastguard Worker    _checks_test(
351*7594170eSAndroid Build Coastguard Worker        name = test_name,
352*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
353*7594170eSAndroid Build Coastguard Worker        expected_checks = _DEFAULT_CHECKS + _DEFAULT_GLOBAL_CHECKS,
354*7594170eSAndroid Build Coastguard Worker        expected_checks_as_errors = _DEFAULT_CHECKS_AS_ERRORS,
355*7594170eSAndroid Build Coastguard Worker        unexpected_checks = ["misc-no-recursion", "readability-function-cognitive-complexity"],
356*7594170eSAndroid Build Coastguard Worker    )
357*7594170eSAndroid Build Coastguard Worker
358*7594170eSAndroid Build Coastguard Worker    return [
359*7594170eSAndroid Build Coastguard Worker        test_name,
360*7594170eSAndroid Build Coastguard Worker    ]
361*7594170eSAndroid Build Coastguard Worker
362*7594170eSAndroid Build Coastguard Workerdef _create_bad_tidy_checks_test(name, tidy_checks, failure_message):
363*7594170eSAndroid Build Coastguard Worker    name = "bad_tidy_checks_fail_" + name
364*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
365*7594170eSAndroid Build Coastguard Worker
366*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
367*7594170eSAndroid Build Coastguard Worker        name = name,
368*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
369*7594170eSAndroid Build Coastguard Worker        tidy_checks = tidy_checks,
370*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
371*7594170eSAndroid Build Coastguard Worker    )
372*7594170eSAndroid Build Coastguard Worker
373*7594170eSAndroid Build Coastguard Worker    expect_failure_test(
374*7594170eSAndroid Build Coastguard Worker        name = test_name,
375*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
376*7594170eSAndroid Build Coastguard Worker        failure_message = failure_message,
377*7594170eSAndroid Build Coastguard Worker    )
378*7594170eSAndroid Build Coastguard Worker
379*7594170eSAndroid Build Coastguard Worker    return [
380*7594170eSAndroid Build Coastguard Worker        test_name,
381*7594170eSAndroid Build Coastguard Worker    ]
382*7594170eSAndroid Build Coastguard Worker
383*7594170eSAndroid Build Coastguard Workerdef _test_bad_tidy_checks_fail():
384*7594170eSAndroid Build Coastguard Worker    return (
385*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_checks_test(
386*7594170eSAndroid Build Coastguard Worker            name = "with_spaces",
387*7594170eSAndroid Build Coastguard Worker            tidy_checks = ["check with spaces"],
388*7594170eSAndroid Build Coastguard Worker            failure_message = "Check `check with spaces` invalid, cannot contain spaces",
389*7594170eSAndroid Build Coastguard Worker        ) +
390*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_checks_test(
391*7594170eSAndroid Build Coastguard Worker            name = "with_commas",
392*7594170eSAndroid Build Coastguard Worker            tidy_checks = ["check,with,commas"],
393*7594170eSAndroid Build Coastguard Worker            failure_message = "Check `check,with,commas` invalid, cannot contain commas. Split each entry into its own string instead",
394*7594170eSAndroid Build Coastguard Worker        )
395*7594170eSAndroid Build Coastguard Worker    )
396*7594170eSAndroid Build Coastguard Worker
397*7594170eSAndroid Build Coastguard Workerdef _create_bad_tidy_flags_test(name, tidy_flags, failure_message):
398*7594170eSAndroid Build Coastguard Worker    name = "bad_tidy_flags_fail_" + name
399*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
400*7594170eSAndroid Build Coastguard Worker
401*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
402*7594170eSAndroid Build Coastguard Worker        name = name,
403*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
404*7594170eSAndroid Build Coastguard Worker        tidy_flags = tidy_flags,
405*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
406*7594170eSAndroid Build Coastguard Worker    )
407*7594170eSAndroid Build Coastguard Worker
408*7594170eSAndroid Build Coastguard Worker    expect_failure_test(
409*7594170eSAndroid Build Coastguard Worker        name = test_name,
410*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
411*7594170eSAndroid Build Coastguard Worker        failure_message = failure_message,
412*7594170eSAndroid Build Coastguard Worker    )
413*7594170eSAndroid Build Coastguard Worker
414*7594170eSAndroid Build Coastguard Worker    return [
415*7594170eSAndroid Build Coastguard Worker        test_name,
416*7594170eSAndroid Build Coastguard Worker    ]
417*7594170eSAndroid Build Coastguard Worker
418*7594170eSAndroid Build Coastguard Workerdef _test_bad_tidy_flags_fail():
419*7594170eSAndroid Build Coastguard Worker    return (
420*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_flags_test(
421*7594170eSAndroid Build Coastguard Worker            name = "without_leading_dash",
422*7594170eSAndroid Build Coastguard Worker            tidy_flags = ["flag1"],
423*7594170eSAndroid Build Coastguard Worker            failure_message = "Flag `flag1` must start with `-`",
424*7594170eSAndroid Build Coastguard Worker        ) +
425*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_flags_test(
426*7594170eSAndroid Build Coastguard Worker            name = "fix_flags",
427*7594170eSAndroid Build Coastguard Worker            tidy_flags = ["-fix"],
428*7594170eSAndroid Build Coastguard Worker            failure_message = "Flag `%s` is not allowed, since it could cause multiple writes to the same source file",
429*7594170eSAndroid Build Coastguard Worker        ) +
430*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_flags_test(
431*7594170eSAndroid Build Coastguard Worker            name = "checks_in_flags",
432*7594170eSAndroid Build Coastguard Worker            tidy_flags = ["-checks=asdf"],
433*7594170eSAndroid Build Coastguard Worker            failure_message = "Flag `-checks=asdf` is not allowed, use `tidy_checks` property instead",
434*7594170eSAndroid Build Coastguard Worker        ) +
435*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_flags_test(
436*7594170eSAndroid Build Coastguard Worker            name = "warnings_as_errors_in_flags",
437*7594170eSAndroid Build Coastguard Worker            tidy_flags = ["-warnings-as-errors=asdf"],
438*7594170eSAndroid Build Coastguard Worker            failure_message = "Flag `-warnings-as-errors=asdf` is not allowed, use `tidy_checks_as_errors` property instead",
439*7594170eSAndroid Build Coastguard Worker        ) +
440*7594170eSAndroid Build Coastguard Worker        _create_bad_tidy_flags_test(
441*7594170eSAndroid Build Coastguard Worker            name = "space_in_flags",
442*7594170eSAndroid Build Coastguard Worker            tidy_flags = ["-flag with spaces"],
443*7594170eSAndroid Build Coastguard Worker            failure_message = "Bad flag: `-flag with spaces` is not an allowed multi-word flag. Should it be split into multiple flags",
444*7594170eSAndroid Build Coastguard Worker        )
445*7594170eSAndroid Build Coastguard Worker    )
446*7594170eSAndroid Build Coastguard Worker
447*7594170eSAndroid Build Coastguard Workerdef _test_disable_global_checks():
448*7594170eSAndroid Build Coastguard Worker    name = "disable_global_checks"
449*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
450*7594170eSAndroid Build Coastguard Worker
451*7594170eSAndroid Build Coastguard Worker    _clang_tidy(
452*7594170eSAndroid Build Coastguard Worker        name = name,
453*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
454*7594170eSAndroid Build Coastguard Worker        tidy_checks = ["-*"],
455*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
456*7594170eSAndroid Build Coastguard Worker    )
457*7594170eSAndroid Build Coastguard Worker
458*7594170eSAndroid Build Coastguard Worker    _checks_test(
459*7594170eSAndroid Build Coastguard Worker        name = test_name,
460*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
461*7594170eSAndroid Build Coastguard Worker        expected_checks = ["-*"] + _DEFAULT_CHECKS,
462*7594170eSAndroid Build Coastguard Worker        expected_checks_as_errors = _DEFAULT_CHECKS_AS_ERRORS,
463*7594170eSAndroid Build Coastguard Worker    )
464*7594170eSAndroid Build Coastguard Worker
465*7594170eSAndroid Build Coastguard Worker    return [
466*7594170eSAndroid Build Coastguard Worker        test_name,
467*7594170eSAndroid Build Coastguard Worker    ]
468*7594170eSAndroid Build Coastguard Worker
469*7594170eSAndroid Build Coastguard Workerdef _cc_library_static_generates_clang_tidy_actions_for_srcs_test_impl(ctx):
470*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
471*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
472*7594170eSAndroid Build Coastguard Worker
473*7594170eSAndroid Build Coastguard Worker    clang_tidy_actions = [a for a in actions if a.mnemonic == "ClangTidy"]
474*7594170eSAndroid Build Coastguard Worker    asserts.equals(
475*7594170eSAndroid Build Coastguard Worker        env,
476*7594170eSAndroid Build Coastguard Worker        ctx.attr.expected_num_actions,
477*7594170eSAndroid Build Coastguard Worker        len(clang_tidy_actions),
478*7594170eSAndroid Build Coastguard Worker        "expected to have %s clang-tidy actions, but got %s; actions: %s" % (
479*7594170eSAndroid Build Coastguard Worker            ctx.attr.expected_num_actions,
480*7594170eSAndroid Build Coastguard Worker            len(clang_tidy_actions),
481*7594170eSAndroid Build Coastguard Worker            clang_tidy_actions,
482*7594170eSAndroid Build Coastguard Worker        ),
483*7594170eSAndroid Build Coastguard Worker    )
484*7594170eSAndroid Build Coastguard Worker
485*7594170eSAndroid Build Coastguard Worker    for a in clang_tidy_actions:
486*7594170eSAndroid Build Coastguard Worker        for input in a.inputs.to_list():
487*7594170eSAndroid Build Coastguard Worker            input_is_expected_header = input.short_path in [f.short_path for f in ctx.files.expected_headers]
488*7594170eSAndroid Build Coastguard Worker            if input in ctx.files._clang_tidy_tools or input_is_expected_header:
489*7594170eSAndroid Build Coastguard Worker                continue
490*7594170eSAndroid Build Coastguard Worker            asserts.true(
491*7594170eSAndroid Build Coastguard Worker                env,
492*7594170eSAndroid Build Coastguard Worker                input in ctx.files.srcs,
493*7594170eSAndroid Build Coastguard Worker                "clang-tidy operated on a file not in srcs: %s; all inputs: %s" % (input, a.inputs.to_list()),
494*7594170eSAndroid Build Coastguard Worker            )
495*7594170eSAndroid Build Coastguard Worker            asserts.true(
496*7594170eSAndroid Build Coastguard Worker                env,
497*7594170eSAndroid Build Coastguard Worker                input not in ctx.files.disabled_srcs,
498*7594170eSAndroid Build Coastguard Worker                "clang-tidy operated on a file in disabled_srcs: %s; all inputs: %s" % (input, a.inputs.to_list()),
499*7594170eSAndroid Build Coastguard Worker            )
500*7594170eSAndroid Build Coastguard Worker
501*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
502*7594170eSAndroid Build Coastguard Worker
503*7594170eSAndroid Build Coastguard Worker_cc_library_static_generates_clang_tidy_actions_for_srcs_test = analysistest.make(
504*7594170eSAndroid Build Coastguard Worker    impl = _cc_library_static_generates_clang_tidy_actions_for_srcs_test_impl,
505*7594170eSAndroid Build Coastguard Worker    attrs = {
506*7594170eSAndroid Build Coastguard Worker        "expected_num_actions": attr.int(mandatory = True),
507*7594170eSAndroid Build Coastguard Worker        "srcs": attr.label_list(allow_files = True),
508*7594170eSAndroid Build Coastguard Worker        "disabled_srcs": attr.label_list(allow_files = True),
509*7594170eSAndroid Build Coastguard Worker        "expected_headers": attr.label_list(allow_files = True),
510*7594170eSAndroid Build Coastguard Worker        "_clang_tidy_tools": attr.label_list(
511*7594170eSAndroid Build Coastguard Worker            default = [
512*7594170eSAndroid Build Coastguard Worker                "@//prebuilts/clang/host/linux-x86:clang-tidy",
513*7594170eSAndroid Build Coastguard Worker                "@//prebuilts/clang/host/linux-x86:clang-tidy.real",
514*7594170eSAndroid Build Coastguard Worker                "@//prebuilts/clang/host/linux-x86:clang-tidy.sh",
515*7594170eSAndroid Build Coastguard Worker            ],
516*7594170eSAndroid Build Coastguard Worker            allow_files = True,
517*7594170eSAndroid Build Coastguard Worker        ),
518*7594170eSAndroid Build Coastguard Worker    },
519*7594170eSAndroid Build Coastguard Worker    config_settings = {
520*7594170eSAndroid Build Coastguard Worker        "@//build/bazel/flags/cc/tidy:allow_local_tidy_true": True,
521*7594170eSAndroid Build Coastguard Worker    },
522*7594170eSAndroid Build Coastguard Worker)
523*7594170eSAndroid Build Coastguard Worker
524*7594170eSAndroid Build Coastguard Workerdef _create_cc_library_static_generates_clang_tidy_actions_for_srcs(
525*7594170eSAndroid Build Coastguard Worker        name,
526*7594170eSAndroid Build Coastguard Worker        srcs,
527*7594170eSAndroid Build Coastguard Worker        expected_num_actions,
528*7594170eSAndroid Build Coastguard Worker        disabled_srcs = None,
529*7594170eSAndroid Build Coastguard Worker        expected_headers = []):
530*7594170eSAndroid Build Coastguard Worker    name = "cc_library_static_generates_clang_tidy_actions_for_srcs_" + name
531*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
532*7594170eSAndroid Build Coastguard Worker
533*7594170eSAndroid Build Coastguard Worker    cc_library_static(
534*7594170eSAndroid Build Coastguard Worker        name = name,
535*7594170eSAndroid Build Coastguard Worker        srcs = srcs,
536*7594170eSAndroid Build Coastguard Worker        tidy_disabled_srcs = disabled_srcs,
537*7594170eSAndroid Build Coastguard Worker        tidy = "local",
538*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
539*7594170eSAndroid Build Coastguard Worker    )
540*7594170eSAndroid Build Coastguard Worker
541*7594170eSAndroid Build Coastguard Worker    _cc_library_static_generates_clang_tidy_actions_for_srcs_test(
542*7594170eSAndroid Build Coastguard Worker        name = test_name,
543*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
544*7594170eSAndroid Build Coastguard Worker        expected_num_actions = expected_num_actions,
545*7594170eSAndroid Build Coastguard Worker        srcs = srcs,
546*7594170eSAndroid Build Coastguard Worker        disabled_srcs = disabled_srcs,
547*7594170eSAndroid Build Coastguard Worker        expected_headers = expected_headers + select({
548*7594170eSAndroid Build Coastguard Worker            "//build/bazel_common_rules/platforms/os:android": ["@//bionic/libc:generated_android_ids"],
549*7594170eSAndroid Build Coastguard Worker            "//conditions:default": [],
550*7594170eSAndroid Build Coastguard Worker        }),
551*7594170eSAndroid Build Coastguard Worker    )
552*7594170eSAndroid Build Coastguard Worker
553*7594170eSAndroid Build Coastguard Worker    return test_name
554*7594170eSAndroid Build Coastguard Worker
555*7594170eSAndroid Build Coastguard Workerdef _test_cc_library_static_generates_clang_tidy_actions_for_srcs():
556*7594170eSAndroid Build Coastguard Worker    return [
557*7594170eSAndroid Build Coastguard Worker        _create_cc_library_static_generates_clang_tidy_actions_for_srcs(
558*7594170eSAndroid Build Coastguard Worker            name = "with_srcs",
559*7594170eSAndroid Build Coastguard Worker            srcs = ["a.cpp", "b.cpp"],
560*7594170eSAndroid Build Coastguard Worker            expected_num_actions = 2,
561*7594170eSAndroid Build Coastguard Worker        ),
562*7594170eSAndroid Build Coastguard Worker        _create_cc_library_static_generates_clang_tidy_actions_for_srcs(
563*7594170eSAndroid Build Coastguard Worker            name = "with_disabled_srcs",
564*7594170eSAndroid Build Coastguard Worker            srcs = ["a.cpp", "b.cpp"],
565*7594170eSAndroid Build Coastguard Worker            disabled_srcs = ["b.cpp", "c.cpp"],
566*7594170eSAndroid Build Coastguard Worker            expected_num_actions = 1,
567*7594170eSAndroid Build Coastguard Worker        ),
568*7594170eSAndroid Build Coastguard Worker    ]
569*7594170eSAndroid Build Coastguard Worker
570*7594170eSAndroid Build Coastguard Workerdef _no_clang_analyzer_on_generated_files_test_impl(ctx):
571*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
572*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
573*7594170eSAndroid Build Coastguard Worker
574*7594170eSAndroid Build Coastguard Worker    clang_tidy_actions = [a for a in actions if a.mnemonic == "ClangTidy"]
575*7594170eSAndroid Build Coastguard Worker    for a in clang_tidy_actions:
576*7594170eSAndroid Build Coastguard Worker        found_clang_analyzer = False
577*7594170eSAndroid Build Coastguard Worker        for arg in a.argv:
578*7594170eSAndroid Build Coastguard Worker            if "-clang-analyzer-*" in arg:
579*7594170eSAndroid Build Coastguard Worker                found_clang_analyzer = True
580*7594170eSAndroid Build Coastguard Worker        asserts.true(env, found_clang_analyzer)
581*7594170eSAndroid Build Coastguard Worker
582*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
583*7594170eSAndroid Build Coastguard Worker
584*7594170eSAndroid Build Coastguard Worker_no_clang_analyzer_on_generated_files_test = analysistest.make(
585*7594170eSAndroid Build Coastguard Worker    impl = _no_clang_analyzer_on_generated_files_test_impl,
586*7594170eSAndroid Build Coastguard Worker    config_settings = {
587*7594170eSAndroid Build Coastguard Worker        "@//build/bazel/flags/cc/tidy:allow_local_tidy_true": True,
588*7594170eSAndroid Build Coastguard Worker    },
589*7594170eSAndroid Build Coastguard Worker)
590*7594170eSAndroid Build Coastguard Worker
591*7594170eSAndroid Build Coastguard Workerdef _test_no_clang_analyzer_on_generated_files():
592*7594170eSAndroid Build Coastguard Worker    name = "no_clang_analyzer_on_generated_files"
593*7594170eSAndroid Build Coastguard Worker    gen_name = name + "_generated_files"
594*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
595*7594170eSAndroid Build Coastguard Worker
596*7594170eSAndroid Build Coastguard Worker    native.genrule(
597*7594170eSAndroid Build Coastguard Worker        name = gen_name,
598*7594170eSAndroid Build Coastguard Worker        outs = ["aout.cpp", "bout.cpp"],
599*7594170eSAndroid Build Coastguard Worker        cmd = "touch $(OUTS)",
600*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
601*7594170eSAndroid Build Coastguard Worker    )
602*7594170eSAndroid Build Coastguard Worker
603*7594170eSAndroid Build Coastguard Worker    cc_library_static(
604*7594170eSAndroid Build Coastguard Worker        name = name,
605*7594170eSAndroid Build Coastguard Worker        srcs = [":" + gen_name],
606*7594170eSAndroid Build Coastguard Worker        tidy = "local",
607*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
608*7594170eSAndroid Build Coastguard Worker    )
609*7594170eSAndroid Build Coastguard Worker
610*7594170eSAndroid Build Coastguard Worker    _no_clang_analyzer_on_generated_files_test(
611*7594170eSAndroid Build Coastguard Worker        name = test_name,
612*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
613*7594170eSAndroid Build Coastguard Worker    )
614*7594170eSAndroid Build Coastguard Worker
615*7594170eSAndroid Build Coastguard Worker    return [
616*7594170eSAndroid Build Coastguard Worker        test_name,
617*7594170eSAndroid Build Coastguard Worker    ]
618*7594170eSAndroid Build Coastguard Worker
619*7594170eSAndroid Build Coastguard Workerdef _clang_tidy_actions_count_no_tidy_env_test_impl(ctx):
620*7594170eSAndroid Build Coastguard Worker    env = analysistest.begin(ctx)
621*7594170eSAndroid Build Coastguard Worker    actions = analysistest.target_actions(env)
622*7594170eSAndroid Build Coastguard Worker
623*7594170eSAndroid Build Coastguard Worker    clang_tidy_actions = [a for a in actions if a.mnemonic == "ClangTidy"]
624*7594170eSAndroid Build Coastguard Worker    asserts.equals(
625*7594170eSAndroid Build Coastguard Worker        env,
626*7594170eSAndroid Build Coastguard Worker        ctx.attr.expected_num_tidy_actions,
627*7594170eSAndroid Build Coastguard Worker        len(clang_tidy_actions),
628*7594170eSAndroid Build Coastguard Worker        "expected to find %d tidy actions, but found %d" % (
629*7594170eSAndroid Build Coastguard Worker            ctx.attr.expected_num_tidy_actions,
630*7594170eSAndroid Build Coastguard Worker            len(clang_tidy_actions),
631*7594170eSAndroid Build Coastguard Worker        ),
632*7594170eSAndroid Build Coastguard Worker    )
633*7594170eSAndroid Build Coastguard Worker
634*7594170eSAndroid Build Coastguard Worker    return analysistest.end(env)
635*7594170eSAndroid Build Coastguard Worker
636*7594170eSAndroid Build Coastguard Worker_clang_tidy_actions_count_no_tidy_env_test = analysistest.make(
637*7594170eSAndroid Build Coastguard Worker    impl = _clang_tidy_actions_count_no_tidy_env_test_impl,
638*7594170eSAndroid Build Coastguard Worker    attrs = {
639*7594170eSAndroid Build Coastguard Worker        "expected_num_tidy_actions": attr.int(),
640*7594170eSAndroid Build Coastguard Worker    },
641*7594170eSAndroid Build Coastguard Worker)
642*7594170eSAndroid Build Coastguard Worker
643*7594170eSAndroid Build Coastguard Worker_clang_tidy_actions_count_with_tidy_true_test = analysistest.make(
644*7594170eSAndroid Build Coastguard Worker    impl = _clang_tidy_actions_count_no_tidy_env_test_impl,
645*7594170eSAndroid Build Coastguard Worker    attrs = {
646*7594170eSAndroid Build Coastguard Worker        "expected_num_tidy_actions": attr.int(),
647*7594170eSAndroid Build Coastguard Worker    },
648*7594170eSAndroid Build Coastguard Worker    config_settings = {
649*7594170eSAndroid Build Coastguard Worker        "@//build/bazel/flags/cc/tidy:with_tidy": True,
650*7594170eSAndroid Build Coastguard Worker    },
651*7594170eSAndroid Build Coastguard Worker)
652*7594170eSAndroid Build Coastguard Worker
653*7594170eSAndroid Build Coastguard Worker_clang_tidy_actions_count_with_allow_local_tidy_true_test = analysistest.make(
654*7594170eSAndroid Build Coastguard Worker    impl = _clang_tidy_actions_count_no_tidy_env_test_impl,
655*7594170eSAndroid Build Coastguard Worker    attrs = {
656*7594170eSAndroid Build Coastguard Worker        "expected_num_tidy_actions": attr.int(),
657*7594170eSAndroid Build Coastguard Worker    },
658*7594170eSAndroid Build Coastguard Worker    config_settings = {
659*7594170eSAndroid Build Coastguard Worker        "@//build/bazel/flags/cc/tidy:allow_local_tidy_true": True,
660*7594170eSAndroid Build Coastguard Worker    },
661*7594170eSAndroid Build Coastguard Worker)
662*7594170eSAndroid Build Coastguard Worker
663*7594170eSAndroid Build Coastguard Workerdef _test_clang_tidy_runs_if_tidy_true():
664*7594170eSAndroid Build Coastguard Worker    name = "clang_tidy_runs_if_tidy_true"
665*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
666*7594170eSAndroid Build Coastguard Worker    with_tidy_test_name = test_name + "_with_tidy_true"
667*7594170eSAndroid Build Coastguard Worker    allow_local_tidy_true_test_name = test_name + "_allow_local_tidy_true"
668*7594170eSAndroid Build Coastguard Worker
669*7594170eSAndroid Build Coastguard Worker    cc_library_static(
670*7594170eSAndroid Build Coastguard Worker        name = name,
671*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
672*7594170eSAndroid Build Coastguard Worker        tidy = "local",
673*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
674*7594170eSAndroid Build Coastguard Worker    )
675*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_no_tidy_env_test(
676*7594170eSAndroid Build Coastguard Worker        name = test_name,
677*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
678*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
679*7594170eSAndroid Build Coastguard Worker    )
680*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_tidy_true_test(
681*7594170eSAndroid Build Coastguard Worker        name = with_tidy_test_name,
682*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
683*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 1,
684*7594170eSAndroid Build Coastguard Worker    )
685*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_allow_local_tidy_true_test(
686*7594170eSAndroid Build Coastguard Worker        name = allow_local_tidy_true_test_name,
687*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
688*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 1,
689*7594170eSAndroid Build Coastguard Worker    )
690*7594170eSAndroid Build Coastguard Worker    return [
691*7594170eSAndroid Build Coastguard Worker        test_name,
692*7594170eSAndroid Build Coastguard Worker        with_tidy_test_name,
693*7594170eSAndroid Build Coastguard Worker        allow_local_tidy_true_test_name,
694*7594170eSAndroid Build Coastguard Worker    ]
695*7594170eSAndroid Build Coastguard Worker
696*7594170eSAndroid Build Coastguard Workerdef _test_clang_tidy_runs_if_attribute_unset():
697*7594170eSAndroid Build Coastguard Worker    name = "clang_tidy_runs_if_attribute_unset"
698*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
699*7594170eSAndroid Build Coastguard Worker    with_tidy_test_name = test_name + "_with_tidy_true"
700*7594170eSAndroid Build Coastguard Worker    allow_local_tidy_true_test_name = test_name + "_allow_local_tidy_true"
701*7594170eSAndroid Build Coastguard Worker
702*7594170eSAndroid Build Coastguard Worker    cc_library_static(
703*7594170eSAndroid Build Coastguard Worker        name = name,
704*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
705*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
706*7594170eSAndroid Build Coastguard Worker    )
707*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_no_tidy_env_test(
708*7594170eSAndroid Build Coastguard Worker        name = test_name,
709*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
710*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
711*7594170eSAndroid Build Coastguard Worker    )
712*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_tidy_true_test(
713*7594170eSAndroid Build Coastguard Worker        name = with_tidy_test_name,
714*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
715*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 1,
716*7594170eSAndroid Build Coastguard Worker    )
717*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_allow_local_tidy_true_test(
718*7594170eSAndroid Build Coastguard Worker        name = allow_local_tidy_true_test_name,
719*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
720*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
721*7594170eSAndroid Build Coastguard Worker    )
722*7594170eSAndroid Build Coastguard Worker    return [
723*7594170eSAndroid Build Coastguard Worker        test_name,
724*7594170eSAndroid Build Coastguard Worker        with_tidy_test_name,
725*7594170eSAndroid Build Coastguard Worker        allow_local_tidy_true_test_name,
726*7594170eSAndroid Build Coastguard Worker    ]
727*7594170eSAndroid Build Coastguard Worker
728*7594170eSAndroid Build Coastguard Workerdef _test_no_clang_tidy_if_tidy_false():
729*7594170eSAndroid Build Coastguard Worker    name = "no_clang_tidy_if_tidy_false"
730*7594170eSAndroid Build Coastguard Worker    test_name = name + "_test"
731*7594170eSAndroid Build Coastguard Worker    with_tidy_test_name = test_name + "_with_tidy_true"
732*7594170eSAndroid Build Coastguard Worker    allow_local_tidy_true_test_name = test_name + "_allow_local_tidy_true"
733*7594170eSAndroid Build Coastguard Worker
734*7594170eSAndroid Build Coastguard Worker    cc_library_static(
735*7594170eSAndroid Build Coastguard Worker        name = name,
736*7594170eSAndroid Build Coastguard Worker        srcs = ["a.cpp"],
737*7594170eSAndroid Build Coastguard Worker        tidy = "never",
738*7594170eSAndroid Build Coastguard Worker        tags = ["manual"],
739*7594170eSAndroid Build Coastguard Worker    )
740*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_no_tidy_env_test(
741*7594170eSAndroid Build Coastguard Worker        name = test_name,
742*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
743*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
744*7594170eSAndroid Build Coastguard Worker    )
745*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_tidy_true_test(
746*7594170eSAndroid Build Coastguard Worker        name = with_tidy_test_name,
747*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
748*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
749*7594170eSAndroid Build Coastguard Worker    )
750*7594170eSAndroid Build Coastguard Worker    _clang_tidy_actions_count_with_allow_local_tidy_true_test(
751*7594170eSAndroid Build Coastguard Worker        name = allow_local_tidy_true_test_name,
752*7594170eSAndroid Build Coastguard Worker        target_under_test = name,
753*7594170eSAndroid Build Coastguard Worker        expected_num_tidy_actions = 0,
754*7594170eSAndroid Build Coastguard Worker    )
755*7594170eSAndroid Build Coastguard Worker    return [
756*7594170eSAndroid Build Coastguard Worker        test_name,
757*7594170eSAndroid Build Coastguard Worker        with_tidy_test_name,
758*7594170eSAndroid Build Coastguard Worker        allow_local_tidy_true_test_name,
759*7594170eSAndroid Build Coastguard Worker    ]
760*7594170eSAndroid Build Coastguard Worker
761*7594170eSAndroid Build Coastguard Workerdef clang_tidy_test_suite(name):
762*7594170eSAndroid Build Coastguard Worker    native.test_suite(
763*7594170eSAndroid Build Coastguard Worker        name = name,
764*7594170eSAndroid Build Coastguard Worker        tests =
765*7594170eSAndroid Build Coastguard Worker            _test_clang_tidy() +
766*7594170eSAndroid Build Coastguard Worker            _test_custom_header_dir() +
767*7594170eSAndroid Build Coastguard Worker            _test_disabled_checks_are_removed() +
768*7594170eSAndroid Build Coastguard Worker            _test_bad_tidy_checks_fail() +
769*7594170eSAndroid Build Coastguard Worker            _test_bad_tidy_flags_fail() +
770*7594170eSAndroid Build Coastguard Worker            _test_disable_global_checks() +
771*7594170eSAndroid Build Coastguard Worker            _test_cc_library_static_generates_clang_tidy_actions_for_srcs() +
772*7594170eSAndroid Build Coastguard Worker            _test_no_clang_analyzer_on_generated_files() +
773*7594170eSAndroid Build Coastguard Worker            _test_no_clang_tidy_if_tidy_false() +
774*7594170eSAndroid Build Coastguard Worker            _test_clang_tidy_runs_if_tidy_true() +
775*7594170eSAndroid Build Coastguard Worker            _test_clang_tidy_runs_if_attribute_unset(),
776*7594170eSAndroid Build Coastguard Worker    )
777